Baa*_*rud 6 sed text-processing sort
我发现自己非常需要一些sed魔法(我真的需要坐下来学习这个)。我有一个包含很多行的文件。在查看之后,我通过在行的开头添加星号 (*) 来标记一些行。
我想用一些sed技巧(如果可能的话)做的是将所有标记的行移动到文件的开头(或结尾——我不挑剔),这样它们就形成了一个块。其他线路(未标记)应该不受干扰。
我怎样才能做这样的事情sed?我知道sed有一些用于移动文本的缓冲区...
cas*_*cas 12
sed 是必不可少的吗?如果你不介意两次通过源文件,这很容易用 grep 完成。
例如
grep '^\*' input > outputfile
grep -v '^\*' input >> outputfile
Run Code Online (Sandbox Code Playgroud)
根据文件的大小,您可以执行以下操作:
sed '/^*/!H;//p;$!d;g;s/\n//'
Run Code Online (Sandbox Code Playgroud)
那堆叠在H不匹配的旧空间行中/^*/。那些匹配的p会在输入中出现时被打印出来。然后从输出中删除所有!不是$最后一行的行d。在最后一行,我们g通过覆盖模式空间来保留空间,然后替换掉第一个\newline 字符s/\n//,因为第一H行每次都会产生一个额外的字符。
这需要一个大缓冲区,因为它已将所有这些行存储在H旧空间中。另一方面,这...
sed '/^*/p;$!d;g;r file' <file |
sed -e '1,/^$/{/./p;d' -e '};/^*/d'
Run Code Online (Sandbox Code Playgroud)
……没有这个要求。
第一个sed print 只打印/^*/匹配的行,直到$最后一行,此时它打印一个空行,然后重新r读出整个输入文件。
第二个sed首先在从第一行到第一个空行的行范围内工作,p所有行至少匹配一个字符,然后d删除批次。在遇到第一个空行后,它会d删除所有匹配的行/^*/。
您不需sed要这样做,您可以使用一些基本的 grep 将星号 (*) 行拉到顶部。比如说你有这个文件:
$ cat sample.txt
1
2
3
4
* 5
* 6
* 7
8
9
10
Run Code Online (Sandbox Code Playgroud)
现在到grepsample.txt 文件,将星号 (*) 行放在首位:
$ cat <(grep '*' sample.txt) <(grep -v '*' sample.txt)
* 5
* 6
* 7
1
2
3
4
8
9
10
Run Code Online (Sandbox Code Playgroud)
上面将运行 2 个 grep,第一个拉出所有带星号的行,而第二个拉出所有未加星号的行。这 2 个命令的输出被重定向为cat使用<()符号的命令的输入。
如果您不想使用 cat + 2 个子shell,您可以按照@terdon 的建议进行操作:
$ grep '*' sample.txt; grep -v '*' sample.txt
Run Code Online (Sandbox Code Playgroud)
这将拉出sample.txt包含星号 (*) 的所有行,然后是所有不包含星号的行。