我目前正在努力找出一个sed命令,它可以提取信息,然后按特定顺序打印。例如,
如果我有这样的文本文档:
kashd[,]->0123asdj01234/
jflskdvnd1234/asdasd[,]->0123asdasd
kashd[,]->0123asdj01234/
jflskdvnd1234/asdasd[,]->0123asdasd
kashd[,]->0123asdj01234/
jflskdvnd1234/asdasd[,]->0123asdasd
然后我要提取每行的以下部分:
[,]->0132
(任意4个随机数字)和
0132/
到目前为止,我的命令是:
sed 's/^.*\(\[,\]->[0-9]\{4\}\|[0-9]\{4\}\/\).*\(\[,\]->[0-9]\{4\}\|[0-9]\{4\}\/\).*$/\1 \2/; '
这个命令确实会提取所有匹配项,但我的问题是我不知道如何更改顺序,因为现在它会打印找到的顺序:
(如果命令在上面的示例文本上运行)
[,]->0123 1234/
1234/ [,]->0123
[,]->0123 1234/
1234/ [,]->0123
1234/ [,]->0123
但我想这样分类:
[,]->0123 1234/
[,]->0123 1234/
[,]->0123 1234/
[,]->0123 1234/
[,]->0123 1234/
而且,我只能使用sed。
最佳答案
因为你不知道哪种模式会首先出现在队列中,我认为最干净的方法是使用保持空间。
下面是我在sed中的做法:
$ sed -E 'h;s/.*([[:digit:]]{4}\/).*/\1/;x;s/.*(\[,\]->[[:digit:]]{4}).*/\1/;G;s/\n/\t/' infile
[,]->0123 1234/
[,]->0123 1234/
[,]->0123 1234/
[,]->0123 1234/
[,]->0123 1234/
[,]->0123 1234/
展开并解释:
h # Copy pattern space to hold space
s/.*([[:digit:]]{4}\/).*/\1/ # Remove everything but dddd/ pattern
x # Swap pattern and hold space
s/.*(\[,\]->[[:digit:]]{4}).*/\1/ # Remove everything but [,]->dddd pattern
G # Append hold space to pattern space
s/\n/\t/ # Replace line break with tab
-E
选项(或较旧GNU sed中的-r
)允许我们不转义()
和{}
。命令也可以在没有它的情况下工作,但是我们必须使用\(\)
和\{\}
。或者,如果您想使用命令:您可以检查一行是否以
[
开头,如果是,则可以交换非空格的to块。如果将此添加到命令中/^\[/!s/^\([^ ]*\)\( *\)\([^ ]*\)$/\3\2\1/
它应该有用。