使用sed用逗号替换前两个空格

时间:2011-07-08 00:30:19

标签: regex perl parsing command-line sed

我有一个以空格分隔的文件,每行有一个可变数量的条目。我想用逗号替换前两个空格来创建一个包含三列的逗号分隔文件。

这是我的意见:

a b  1 2 3 3 2 1
c d  44 55 66 2355
line http://google.com 100 200 300
ef jh  77 88 99
z y 2 3 33

这是我想要的输出:

a,b,1 2 3 3 2 1
c,d,44 55 66 2355
line,http://google.com,100 200 300
ef,jh,77 88 99
z,y,2 3 33

我正在尝试在sed命令中使用perl正则表达式,但我无法让它工作。首先我尝试捕捉一个单词,然后是空格,然后是另一个单词,但这只适用于第1,2和5行:

$ cat test | sed -r 's/(\w)\s+(\w)\s+/\1,\2,/'
a,b,1 2 3 3 2 1
c,d,44 55 66 2355
line http://google.com 100 200 300
ef jh  77 88 99
z,y,2 3 33

我也尝试捕获空格,一个单词,然后是更多的空格,但这给了我相同的结果:

$ cat test | sed -r 's/\s+(\w)\s+/,\1,/'
a,b,1 2 3 3 2 1
c,d,44 55 66 2355
line http://google.com 100 200 300
ef jh  77 88 99
z,y,2 3 33

我也试着这样做。?通配符,但这对第4行做了一些有趣的事。

$ cat test | sed -r 's/\s+(.?)\s+/,\1,/'
a,b,1 2 3 3 2 1
c,d,44 55 66 2355
line http://google.com 100 200 300
ef jh,,77 88 99
z,y,2 3 33

非常感谢任何帮助!

6 个答案:

答案 0 :(得分:6)

这个怎么样:

sed -e 's/\s\+/,/' | sed -e 's/\s\+/,/'

使用单个sed命令可能是可能的,但这确实是一种简单的方法:)

我的输出:

a,b,1 2 3 3 2 1
c,d,44 55 66 2355
line,http://google.com,100 200 300
ef,jh,77 88 99
z,y,2 3 33

答案 1 :(得分:4)

试试这个:

sed -r 's/\s+(\S+)\s+/,\1,/'

在你的一次尝试中,用\w(一个或多个非空间字符)替换了\S+(一个“字”字符)。

答案 2 :(得分:3)

只需提供多个sed参数,即可为-e的单个实例提供多个命令。

要做前两个,只需使用:

sed -e 's/\s\+/,/' -e 's/\s\+/,/'

这基本上按顺序在行上运行两个命令,第一个执行第一个空白块,第二个执行下一个。

以下成绩单显示了这一点:

pax$ echo 'a b  1 2 3 3 2 1
c d  44 55 66 2355
line http://google.com 100 200 300
ef jh  77 88 99
z y 2 3 33
' | sed -e 's/\s\+/,/' -e 's/\s\+/,/'

a,b,1 2 3 3 2 1
c,d,44 55 66 2355
line,http://google.com,100 200 300
ef,jh,77 88 99
z,y,2 3 33

答案 3 :(得分:2)

Sed s///支持一种方式来说明要替换的模式的出现:只需将n添加到命令的末尾以仅替换n次出现。因此,要替换第一次和第二次出现的空格,只需使用它:

$ sed 's/  */,/1;s/  */,/2' input
a,b ,1 2 3 3 2 1
c,d ,44 55 66 2355
line,http://google.com 100,200 300
ef,jh ,77 88 99
z,y 2,3 33

编辑:阅读其他提议的解决方案,我注意到1之后的2s/ */,/不仅是不必要的,而且显然是错误的。默认情况下,s///只是替换第一次出现的模式。因此,如果我们依次有两个相同的s///,它们将替换第一次和第二次出现。你需要的只是

$ sed 's/  */,/;s/  */,/' input 

(注意,如果用分号分隔,可以在一个表达式中放入两个sed命令。有些sed实现在s///命令后不接受分号;使用换行符分隔命令,在此情况)。

答案 4 :(得分:1)

Perl解决方案是:

perl -pe '$_=join ",", split /\s+/, $_, 3' some.file

答案 5 :(得分:0)

不确定sed / perl,但这是一个(丑陋的)awk解决方案。它只打印字段1-2,用逗号分隔,然后用空格分隔剩余的字段:

awk '{
  printf("%s,", $1)
  printf("%s,", $2)
  for (i=3; i<=NF; i++)
    printf("%s ", $i)
    printf("\n")
}' myfile.txt