加入匹配的行

时间:2014-12-17 08:27:07

标签: sed

鉴于此示例文件

$ cat infile.txt
foo
  hello
bar
  world
baz
qux

我想加入所有不以空格开头的行,最后结束 此

foo:bar:baz:qux

我试过这个

$ sed ':a;N;s/\n/:/;ba' infile.txt
foo:  hello:bar:  world:baz:qux

但它加入了所有的行。出于这个问题的目的,我更喜欢sed 溶液

阅读完答案和评论后,我有了这些工作命令

$ sed '/ /!H;$!d;x;s/\n//;s//:/g' infile.txt
foo:bar:baz:qux

$ awk '!/ /{printf s++?":"$0:$0}' infile.txt
foo:bar:baz:qux

7 个答案:

答案 0 :(得分:3)

sed '/^ /d; H; ${ x; s/\n/:/g; s/^://; p; }; d'

第一部分/^ /d;删除以空白开头的行。 H在换行符后将模式空间附加到保留空间。 ${ x; s/\n/:/g; s/^://; p; };处理最后一行。它交换模式并保持空间,用冒号替换换行符,删除第一个冒号,然后打印结果。最后的d会删除这些行,以便您只看到最终输出。

答案 1 :(得分:2)

仅使用sed:

~$ sed -ne '{/^[^ ]/{H};${x;s/\n/:/g;s/^://;p}}' infile.txt
foo:bar:baz:qux

对于每一行,如果它不以空格开头,则附加到保持缓冲区 最后,交换模式并保持缓冲区,并用\n替换:,然后关注可能的第一个:并打印。

有点不那么难看:

~$ sed -ne '/^ /!H;${x;s/\n/:/g;s/^://;p}' infile.txt
foo:bar:baz:qux

使用速度优化(根据this file,感谢@StevenPenny)

~$ sed -ne '/^ /!H;${x;/\n/s///;s//:/g;p}' infile.txt

追加保留缓冲区,除非以空格开头。在最后一行,将hold缓冲区设置为pattern,如果匹配/\n/,则删除第一个(s///),并用:s//:/g/)替换其他缓冲区。


如果你不介意管道sed命令:

~$ sed '/^ /d' infile.txt | sed ':a;N;s/\n/:/;ba'
foo:bar:baz:qux

只需删除以空格开头的行,然后加入行。

答案 2 :(得分:2)

我知道只有你正在寻找sed只有答案,但我发布一个awk命令只是为了表明与awk相比,sed是多么神秘:

awk -v ORS=: '/^[^ ]/' file
foo:bar:baz:qux:

如果你不想要上一个:,那么:

awk -v ORS=: '/^[^ ]/{s=s $0 ORS} END{printf "%s\n", substr(s, 1, length(s)-1)}' file
foo:bar:baz:qux

答案 3 :(得分:1)

试试这个:

$ grep -e '^[^ ]' infile.txt | tr '\n' ':' | sed 's/.$/\n/'
foo:bar:baz:qux

答案 4 :(得分:0)

尝试类似:

sed -nr '/^[^ ]/p' test.txt | sed ':a;N;s/\n/:/;ba'

答案 5 :(得分:0)

使用sed:

sed -e ':a;N;$!ba;s/\n/:/g; s/ [^:]*://g' File

此处,:a;N;$!ba;s/\n/ /g将删除所有换行符,这将提供foo: hello:bar: world:baz:qux。然后s/ [^:]*://gspace to :中删除。如果每行中存在其他:和空格,则每次都不起作用:-)。按照你的例子,它会的。

使用awk:

awk '!/^ /{if(a){a=a ":" $0}else{a=a $0}} END{print a}' File

答案 6 :(得分:0)

好的,好吧,这不是sed ......无论如何;

perl -p0e 's/\n( .*\n)*/:/g'
  • -0 slurp输入文件
  • -p在处理后打印“it”

(谢谢大家提供的精彩sed和awk解决方案!!)