3

我有一个像这样的文本文件:

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

关闭,但没有雪茄。关于为什么我的正则表达式不起作用的任何想法?

4

3 回答 3

4

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

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

试试这个:

$ sed -re 's/ ([A-Z])/-\1/g'

请注意,这没有重叠匹配:

FOO BAR PIPPO PLUTO 31337 1010
   --  ==    --
   1   2     3
于 2011-03-14T22:39:41.133 回答
1
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
于 2011-03-14T22:47:43.047 回答
0

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

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 参数)

于 2011-03-14T22:43:47.980 回答