Replace characters using regex grouping with sed

I have a text file:

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

I need to enable it:

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

The best I could do was:

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

but the way out

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

Close but no cigar. Any idea on why my regex isn't working?

+3
source share
3 answers

You cannot have matching matches. "BAR PIPPO" was not detected because "BAR" is already consumed when matching "FOO BAR".

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

Try this instead:

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

Note that this does not have matching matches:

FOO BAR PIPPO PLUTO 31337 1010
   --  ==    --
   1   2     3
+4
source
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
+1

Very close. You do not need to match more than one letter, although you just need to write a letter:

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 parameters adjusted for BSD sed)

0
source

All Articles