先热身一下,选一个sed1line中比较复杂点的命令
# reverse each character on the line (emulates "rev") #反转一行中每个字符的顺序(类似"rev") sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//'
我们选取一行文字是 123
那么执行后模式空间中的内容应该按下边的顺序变化
处理第一行的时候,行中存在”\n”,不匹配/\n/!G; G命令不执行,得
123\n
然后执行s/\(.\)\(.*\n\)/&\2\1/; &代表s中的整个正则表达式内容
得
123\n23\n1
执行//D
23\n1
因为是D命令,此时pattern space仍然有内容,脚本停止读入下行,控制转移到脚本顶部,形成循环。往下继续,
模式空间有\n
所以/\n/!G;中G不执行
再来s...
23\n3\n21
再D
3\n21
循环,G不执行
再来s...
3\n\n321
再D
\n321
循环
G和s和D都不执行
执行最后的s/.//
321
这里的难点在于怎样理解D命令。虽然看英文比较头疼,但还是得看下sed man中关于D命令的解释,以更清晰D命令的运作。
下面是D命令的man:
Delete up to the first embedded newline in the pattern space. Start next cycle, but skip reading from the input if there is still data in the pattern space.
翻译成中文:
删除当前模式空间的第一个嵌入行,开始新的循环(控制转到脚本顶部)。但是如果模式空间仍然有数据,那么跳过读取下行。
回顾下sed基础二中的内容:
删除命令D是删除命令d的多行形式,区别在于d删除模式空间的内容并读入新行,从而在脚本顶端重新使用编辑方法。
D只删除多行模式空间的第一个嵌入的换行符以前的内容,它不会导致读入新行,相反,它返回到脚本的顶端,将这些指令应用与模式空间剩余的内容。
这条命令就完全清楚了。