Regex 用sed替换使用正则表达式分组的字符

Regex 用sed替换使用正则表达式分组的字符,regex,sed,grouping,backreference,Regex,Sed,Grouping,Backreference,我有一个如下的文本文件: FOO BAR PIPPO PLUTO 31337 1010 FOOZ BAZ 130 VERY LONG LINE LIKE THIS THEN A NUMBER LIKE 42 我需要把它变成: FOO-BAR-PIPPO-PLUTO 31337 1010 FOOZ-BAZ 130 VERY-LONG-LINE-LIKE-THIS-THEN-A-NUMBER-LIKE 42 我所能做的就是: sed -re 's/([A-Z]+)( )([A-Z]+)/\1-\

我有一个如下的文本文件:

FOO BAR PIPPO PLUTO 31337 1010
FOOZ BAZ 130
VERY LONG LINE LIKE THIS THEN A NUMBER LIKE 42
我需要把它变成:

FOO-BAR-PIPPO-PLUTO 31337 1010
FOOZ-BAZ 130
VERY-LONG-LINE-LIKE-THIS-THEN-A-NUMBER-LIKE 42
我所能做的就是:

sed -re 's/([A-Z]+)( )([A-Z]+)/\1-\3/g'
但结果是

FOO-BAR PIPPO-PLUTO 31337 1010
FOOZ-BAZ 130
VERY-LONG LINE-LIKE THIS-THEN A-NUMBER LIKE 42

很近,但没有雪茄。你知道为什么我的正则表达式不起作用吗?

你不能有重叠的匹配。未检测到“BAR PIPPO”,因为在匹配“FOO BAR”时已使用“BAR”

请尝试以下方法:

$ sed -re 's/ ([A-Z])/-\1/g'
请注意,这没有重叠的匹配:

FOO BAR PIPPO PLUTO 31337 1010
   --  ==    --
   1   2     3

非常接近。不过,您不需要匹配多个字母-您只需要字母空格字母:

sed -Ee 's/([A-Z])( )([A-Z])/\1-\3/g' foo.txt 
FOO-BAR-PIPPO-PLUTO 31337 1010
FOOZ-BAZ 130
VERY-LONG-LINE-LIKE-THIS-THEN-A NUMBER-LIKE 42
(根据BSD sed调整sed参数)

只需查找后跟非数字的空格,并将该空格替换为
-
。这样做的优点是,它适用于具有非字母数字字符的行

概念证明
对于第三个例子,这不太适用。它忽略了
中的空格,然后是一个数字。但是最好只匹配一个字符,我也更新了我的答案。好的,这就足够了,谢谢你对重叠的解释!
sed -Ee 's/([A-Z])( )([A-Z])/\1-\3/g' foo.txt 
FOO-BAR-PIPPO-PLUTO 31337 1010
FOOZ-BAZ 130
VERY-LONG-LINE-LIKE-THIS-THEN-A NUMBER-LIKE 42
sed 's/ \([^0-9]\)/-\1/g'
$ cat ./infile
FOO BAR PIPPO PLUTO 31337 1010
FOOZ BAZ 130
VERY LONG LINE LIKE THIS THEN A NUMBER LIKE 42
THIS LINE HAS $ODD$ #CHARS# IN %IT% 42

$ sed 's/ \([^0-9]\)/-\1/g' ./infile
FOO-BAR-PIPPO-PLUTO 31337 1010
FOOZ-BAZ 130
VERY-LONG-LINE-LIKE-THIS-THEN-A-NUMBER-LIKE 42
THIS-LINE-HAS-$ODD$-#CHARS#-IN-%IT% 42