为什么这两个sed命令得到不同的结果?

时间:2014-04-04 21:30:08

标签: regex csv sed

csv文件example.csv,它有

hello,world,wow
this,is,amazing

我想得到第一个列元素,在开始时我写了一个sed命令,如:

sed -n 's/\([^,]*\),*/\1/p' example.csv

输出:

helloworld,now
thisis,amazing

然后我将命令修改为以下内容并得到我想要的内容:

sed -n 's/\([^,]*\).*/\1/p' example.csv

输出:

hello
this 

command1我使用了逗号(,)和命令2我用点(。)替换了逗号,它按预期工作,任何人都可以解释sed如何真正起作用以获得第一个输出?背后的故事是什么?是因为点(。)还是因为替换组&向后引用?

5 个答案:

答案 0 :(得分:3)

在两个正则表达式中,([^,]*)将使用字符串的相同部分 - 第一个遇到逗号之前的所有符号。显然,区别在于这些正则表达式的剩余部分是如何处理的。

在第一个中,它是,* - 零个或多个逗号符号。显然它可能消耗的是 逗号本身 - 该行的其余部分未被模式覆盖。

在第二个中,它是.* - 任何符号中的零个或多个。它完全覆盖了剩下的琴弦并不是一个大惊喜 - 因为它没有什么可以阻止的;任何是,好吧,任何。 )

在这两种情况下,字符串的模式覆盖部分都被捕获组的内容所取代(正如我已经说过的那样,'第一个逗号之前的所有符号') - 以及其余部分所涵盖的内容刚删除正则表达式。所以在第一种情况下,第一个逗号被删除,第二个 - 逗号和字符串的其余部分。

答案 1 :(得分:1)

背后的原因是模式只匹配单词的第一部分,即只替换Hello部分。部分*采用任意数量的逗号,然后没有任何东西被设置为下一个,即没有其他东西与模式匹配。例如:

hello,,,,,,,,,,,,,,,,,,world

将被替换为

helloworld

一个很好的例子是

sed -n 's/\([^,]*\),*$/\1/p' example.csv

当且仅当所有逗号都在行的末尾并且将修剪它们时,这将起作用,例如

hello,,,,,,

希望这会使问题更加清晰。

答案 2 :(得分:0)

在正则表达式上。 (点)是一个单个字符的占位符。

答案 3 :(得分:0)

如果您喜欢第一个字,为什么不使用awk

awk -F, '{print $1}' file
hello
this

sed与后方参考

一起使用
sed -nr 's/([^,]*),.*/\1/p' file
hello
this

似乎要使它工作,你需要.*所以它得到整行 r选项使您无需转义括号\(

答案 4 :(得分:0)

我可以使用sed建议吗?

cut -d, -f1 example.csv

就个人而言,我是一个巨大的sed粉丝,但在这种情况下cut更合适。