I was going through USEFUL ONE-LINE SCRIPTS FOR SED by Eric Pement and
noticed this interesting sed expression which I am having trouble
deciphering:
sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//'
Formatting it for better visual:
sed '
/\n/ !G
s/\(.\)\(.*\n\)/&\2\1/
//D
s/.//
'
What it does is reverse lines just like `rev' program.
Could anyone comment how this particular expression works?
At the moment I don't understand in which cases the /\n/ matches
(in both //D and /\n/ !G commands).
For example a test program: echo test | sed -n '/\n/ p' never prints
anything.
Thanks!
P.Krumins
This is a very interesting sed command line. :-)
/\n/!G
this line is trival, it means if there is no newline in your input
stream, then you append one at the end.
s/\(.\)\(.*\n\)/&\2\1/;
a simple s/// expression where you group the first character as \1, all
others as \2, then replace these whole matched stuff with "&\2\1",
where & is the whole matched text or "\1\2".. so if the input string is
"1234" then after s/// expression, it becomes "1234\n234\n1".
//D;
this statement is the key, since empty pattern matches the last
existing regex, so it's exactly the same as: /\(.\)\(.*\n\)/D
D command means(From my pocket reference): Delete from the start of the
input till the first embedded newline and then *resume* editing with
first command in script. so you got a loop: as long as
/\(.\)\(.*\n\)/ satisfied, sed will resume all previous operations to
handle the text in the pattern space..
After several loop, the text in the pattern space becomes "\n4321",
when /\(.\)\(.*\n\)/ fails, and then the sed goes to the next command.
s/.// : remove the first character in the pattern space which is the
newline..
So, after you understand what "//D" does, then you know how your script
works.
Hope this helps.
Xicheng
Thanks, now I fully understand this expression :)
P.Krumins