alexsuv
alexsuv

Reputation: 45

Sed: find, replace and then append result to original line

I am on Mac, I want to find a pattern in lines, replace it with something, then append the resulting string to the end of the original line. Here is what I tried:

echo "test='123'" | sed -E  '/([^a-z])/ s/$/ \1/' 

sed: 1: "/([^a-z])/ s/$/ \1/": \1 not defined in the RE

What do I need to define \1? I thought I did it with ([^a-z]). No?

Edit: Perhaps this code will represent better what I want:

1) echo "test='123'" | sed 's/[a-zA-Z0-9]//g'

2) I want the new line = original line + line #1 above

In other words:

Before (what I get): test='123'

After (what I want): test='123' =''

Upvotes: 1

Views: 797

Answers (1)

Enlico
Enlico

Reputation: 28470

You can edit this command this way:

echo "test='123'" | sed -E 'h;s/([a-zA-Z0-9])//g;G;s/(.*)\n(.*)/\2\1/'

For readability, the script, line by line, reads

h
s/([a-zA-Z0-9])//g
G
s/(.*)\n(.*)/\2\1/
  • h stores the current line in the hold space,
  • your s command does what it does
  • G appends the content of the hold space, i.e. the original line, to the pattern space, i.e. the current line as you have edited it, putting a newline \n in between.
  • another s command reorders the two pieces, also removing the \n that the G command inserted.

Comments

  • Your original attempt sed -E '/([^a-z])/ s/$/ \1/' could not work because \1 refers to what is captured by the leftmost (…) group in the search portion of the s command, it does not "remember" the group(s) you used to address the line.
  • Once you print the pattern space with p, a newline comes with it, and once it's been printed, there's no way you can remove it within the same sed program.

Upvotes: 1

Related Questions