There is a loop in this code that get's confusing to see. This bit:
Keeps looping, shifting the characters
34\n21 until we're left with
\n4321, where it then drops out of the loop.
The description by catonmat is spot on so I'm including it here: 37. Reverse a line (emulates "rev" Unix command)..
The first line
"/\n/ !G" appends a newline to the end of the pattern space if there was none.
The second line
"s/\(.\)\(.*\n\)/&\2\1/" is a simple
s/// expression which groups the first character as
\1 and all the others as
\2. Then it replaces the whole matched string with
"&" is the whole matched text (
"\1\2"). For example, if the input string is "1234" then after the
s/// expression, it becomes
The third line is
"//D". This statement is the key in this one-liner. An empty pattern
// matches the last existing regex, so it's exactly the same as:
/\(.\)\(.*\n\)/D. The "D" command deletes from the start of the input till the first newline and then resumes editing with first command in script. It creates a loop. As long as
/\(.\)\(.*\n\)/ is satisfied, sed will resume all previous operations. After several loops, the text in the pattern space becomes
/\(.\)\(.*\n\)/ fails and sed goes to the next command.
The fourth line
"s/.//" removes the first character in the pattern space which is the newline char. The contents in pattern space becomes
"4321" -- reverse of
There you have it, a line has been reversed.