大家。 我不了解sed脚本编程中的美元符号($),它代表文件的最后一行还是sed的计数器? 我想颠倒/ etc / passwd的行的顺序(模拟" tac")。如下:
$ cat /etc/passwd | wc -l ----> 52 // line numbers
$ sed '1!G;h;$!d' /etc/passwd | wc -l ----> 52 // working correctly
$ sed '1!G;h;$d' /etc/passwd | wc -l ----> 1326 // no ! followed by $
$ sed '1!G;h;$p' /etc/passwd | wc -l ----> 1430 // instead !d by p
最后两个例子不能正常工作,谁能告诉我美元符号代表什么意思?
答案 0 :(得分:3)
所有命令“正常工作”。他们只是做一些你不期望的事情。让我们考虑第一个版本:
sed '1!G;h;$!d
从前两个命令开始:
1!G; h
执行了这两个命令后,模式空间和保持空间都包含到目前为止所有行读取,但顺序相反。
此时,如果我们什么都不做,sed
将采取默认操作,即打印模式空间。所以:
读完第一行后,会打印第一行。
读完第二行后,会打印第二行,然后是第一行。
读完第三行后,会打印第三行,然后是第二行,接着是第一行。
等等。
如果我们效仿tac
,我们不希望这样。我们希望它在最后一行读完后才能打印。所以,这就是以下命令的来源:
$!d
$
表示最后一行。 $!
表示不是最后一行。如果我们不在最后一行,则$!d
表示删除。因此,这告诉sed
删除模式空间,除非我们在最后一行,在这种情况下它将被打印,以相反的顺序显示所有行。
考虑到这一点,请考虑您的第二个例子:
sed '1!G;h;$d'
这将打印除最后一个之外的所有部分tac
。
你的第三个例子:
sed '1!G;h;$p'
这会将所有部分tac
打印到最后一个,但最后一个打印两次:$p
是除了隐式打印之外的最后一行的模式空间的显式打印无论如何都会发生。