任何人都可以解释"sed-regex here"中发生的事情

Sha*_*n K 4 regex bash sed

我正在使用正则表达式练习sed命令,但结果并不像预期的那样.我在mac Sierra上使用终端.这是输入数据:

Mark watermellons 12
Robert pears 4
Terry oranges 9
Lisa peaches 7
Susy oranges 12
Mark grapes 39
Anne mangoes 7
Greg pineapples 3
Oliver rockmellons 2
Betty limes 14
Run Code Online (Sandbox Code Playgroud)

我正在尝试交换第一列和第二列.我使用了这个命令:

sed 's/\(.+\) \(.+\) /\2 \1/ ' file.txt
Run Code Online (Sandbox Code Playgroud)

此命令返回相同的输入.但是当我使用时,

sed 's/\(.*\) \(.*\) /\2 \1 /' file.txt
Run Code Online (Sandbox Code Playgroud)

列正在交换.为什么"+"不匹配,因为每行至少有一个字符.

另外,当我使用时

sed 's/\(.*\) \(.*\)/\2 \1 /' file.txt 
Run Code Online (Sandbox Code Playgroud)

第一个括号是捕获前两列,第二个是最后一列,为什么第一个括号没有捕获第一列?

Sto*_*ica 8

问题不在于你对正则表达式和贪婪匹配等方面的理解.问题只是在问题+中的示例使用中没有实现.

sed,在默认情况下,+并不意味着"一个或多个前面的符号",你可能会从其他的正则表达式语法习惯了.要在BSD这项工作sed(因为你是在OSX),则需要启用与扩展正则表达式-E,也改变捕获组语法:

sed -E 's/(.+) (.+) /\2 \1/ ' file.txt
Run Code Online (Sandbox Code Playgroud)

另请注意,这+基本上只是一个快捷方式,因此您可以始终以良好的老式方式编写它:

sed 's/\(..*\) \(..*\) /\2 \1/' file.txt
Run Code Online (Sandbox Code Playgroud)

顺便说一句,总是要注意BSD sed和GNU 之间的区别sed.例如,这在GNU中可以正常工作,sed但在BSD中没有sed:

sed 's/\(.\+\) \(.\+\) /\2 \1/ ' file.txt
Run Code Online (Sandbox Code Playgroud)

这篇文章的前两个解决方案同时适用于GNU和BSD sed.只要有可能,最好选择适用于两者的语法,以防止各种调试地狱.