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"
。你有它,一条线被颠倒了。