在 sed 中反转一行?

mun*_*ish 6 sed

 echo 1234 |   sed '
       /\n/ !G
       s/\(.\)\(.*\n\)/&\2\1/
       //D
       s/.//
     ' 
Run Code Online (Sandbox Code Playgroud)

我无法理解上面的sed代码。

我的理解是:

PATTERN SPACE=1234
first operation /\n/ !G ---> 1234\n(if \n is  not found it is appended at th end)
                s/\(.\)\(.*\n\)/&\2\1/ ----> 1234\n234\n1
                //D ----> \n234\n1(deletes upto newline and commands
                                   from the beginning are applied to the 
                                   existing pattern space)
PATTERN SPACE=\n234\n1
second operation /\n/ !G ---> skipped since  \n234\n1 has newline now
                 s/\(.\)\(.*\n\)/&\2\1/ ----> \n234\n1234\n
                 //D ----> \n234\n1234\n
Run Code Online (Sandbox Code Playgroud)

看来我做错了什么。

slm*_*slm 10

这段代码中有一个循环令人困惑。这一点:

   s/\(.\)\(.*\n\)/&\2\1/
   //D
Run Code Online (Sandbox Code Playgroud)

继续循环,将字符移动234\n1到 ,34\n21直到剩下\n4321,然后退出循环。

catonmat 的描述是正确的,所以我把它包括在这里:37. 反转一行(模拟“rev”Unix 命令)。.

摘抄

如果没有,第一行在"/\n/ !G"模式空间的末尾追加一个换行符。

第二行"s/\(.\)\(.*\n\)/&\2\1/"是一个简单的s///表达式,它将第一个字符分组为\1,所有其他字符分组为\2。然后它将整个匹配的字符串替换为"&\2\1",其中"&"是整个匹配的文本 ( "\1\2")。例如,如果输入字符串是“1234”,那么在s///表达式之后,它变成"1234\n234\n1".

第三行是"//D"。这句话是这一行的关键。空模式//匹配最后一个现有的正则表达式,因此它与: 完全相同/\(.\)\(.*\n\)/D。“D”命令从输入的开始处删除,直到第一个换行符,然后使用脚本中的第一个命令恢复编辑。它创建了一个循环。只要/\(.\)\(.*\n\)/满足,sed 就会恢复之前的所有操作。经过几次循环后,模式空间中的文本变为"\n4321"。然后/\(.\)\(.*\n\)/失败并且 sed 转到下一个命令。

第四行"s/.//"删除模式空间中的第一个字符,即换行符。模式空间中的内容变为"4321"- 的反向"1234"

你有它,一条线被颠倒了。