0

Modified working solution:

sed -r "s/(\.*)\[/\1\r[/g"

Better solution:

sed -r "s/(.*)\[/\1\r[/g"

Broken down:

s/
(\.*)\[    -String to Capture followed by [
/
\1\r[      -Line to replace with
/g" 

I believe for subsequent strings, more of these are made
(\.*) but in the same order they appear from left to right, the variables are referenced.

Please try to keep answers as a working sed line with a description of the replace operation.

I actually do want to learn how to use variables in sed. So if you have another solution, I'm all ears, but I really do wish to learn how to manipulate variables in sed.

I've tried

$1, %1 and 1

as a combination of these \$1, \%1 \1 and /$1 /%1 /1

to no avail.

Here's my starting working script that replaces the matching section with a blank section.

sed -e "s/\.*\[//g" testfile.txt

What I want to do with the script is replace (* representing any prior (nonwhitespace) string)

*[ 

with (no blank lines or tabs in-between either)

*
[

So I figured something like

C:\temp>sed -e "s/\.*\[/\1/g" testfile.txt
sed: -e expression #1, char 12: invalid reference \1 on `s' command's RHS
thistleknot
  • 1,098
  • 16
  • 38

2 Answers2

2

I think you want something like this:

$ cat file.txt 
this should be the first line*[and this should be the second
$ sed -r 's/([^*]*\*)/\1\n/' file.txt 
this should be the first line*
[and this should be the second

Note that using the -r option means you don't need to escape the parens. If you don't use -r you must replace ( with \( and ) with \) The first capture group is within the first parens

([^*]*\*)

which captures everything before (and including) the first *.

The replacement (\1\n) prints the first capture group, followed by a newline, followed by the rest of the line.

And if you're really interested in learning sed, check out this tutorial

skamazin
  • 757
  • 5
  • 12
  • description of the replace operation? Is this a capture group or something? (.*?\*). I was hoping how to learn variables through this post. With no context and explanation of how you arrived from my old method to this. I don't learn anything. Is the -r necessary due to the nature of the sed line? Btw, I'm using gnuwin32, so my sed arguments require "" vs '', but that I know how to address... I don't even see the closing /g in your sed line. – thistleknot Aug 18 '14 at 13:05
  • I do not wish to match a "second" line btw. I specifically had this problem limited to star[ vs star[star. By breaking at the [, the data after that point will naturally fall behind the [ – thistleknot Aug 18 '14 at 13:09
  • $ sed -r 's/(.*?\*)(\[)/\1\n\2/' file.txt – thistleknot Aug 18 '14 at 13:10
  • Thank you! It really explains a lot! – thistleknot Aug 18 '14 at 13:19
  • @Unihedron not sure if the `*` has to be escape in the character class for `sed` (I know normally it's treated literally, but `sed` can be weird about meta characters) – skamazin Aug 20 '14 at 19:10
  • @Unihedron So escape the `*` in the character class or not? – skamazin Aug 20 '14 at 19:13
1

To use variables as you described, you need \( and \) to group the part you want to reference. So in your case you want to do

sed -e 's/\(\.*\)\[/\1\r\n[/g' testfile.txt

So \1 refers to the part \(\.*\).

CS Pei
  • 10,869
  • 1
  • 27
  • 46
  • idkw but that creates newlines inbetween, but it does show me how to capture variables. Thank you. Removing the \n outputs no newlines in shell (cmd prompt or cygwin), but when pasted into notepad it does. – thistleknot Aug 18 '14 at 13:12