Soluzione 1:
Usa sed -e "s/[[:space:]]\+/ /g"
Ecco una spiegazione:
[ # start of character class
[:space:] # The POSIX character class for whitespace characters. It's
# functionally identical to [ \t\r\n\v\f] which matches a space,
# tab, carriage return, newline, vertical tab, or form feed. See
# https://en.wikipedia.org/wiki/Regular_expression#POSIX_character_classes
] # end of character class
\+ # one or more of the previous item (anything matched in the brackets).
Per la tua sostituzione, vuoi solo inserire uno spazio. [:space:]
non funzionerà lì poiché è un'abbreviazione per una classe di caratteri e il motore regex non saprebbe quale carattere inserire lì.
Il +
deve essere sfuggito nella regex perché con il motore regex di sed +
è un carattere normale mentre \+
è un metacarattere per 'uno o più'. A pagina 86 di Padroneggiare le espressioni regolari , Jeffrey Friedl menziona in una nota a piè di pagina che ed e grep usavano le parentesi sfuggite perché "Ken Thompson riteneva che le espressioni regolari sarebbero state usate per funzionare principalmente con Ccode, dove la necessità di abbinare le parentesi grezze sarebbe stata più comune del backreferencing". Presumo che la pensasse allo stesso modo riguardo al segno più, da qui la necessità di sfuggirgli per usarlo come metacarattere. È facile farsi inciampare da questo.
In sed dovrai sfuggire a +
, ?
, |
, (
e )
. o usa -r per usare espressioni regolari estese (quindi sembra sed -r -e "s/[[:space:]]\+/ /g"
o sed -re "s/[[:space:]]\+/ /g"
Soluzione 2:
Puoi usare il -s
("squeeze") opzione di tr
:
$ tr -s '[:blank:]' <<< 'test.de. 1547 IN SOA ns1.test.de. dnsmaster.test.de. 2012090701 900 1000 6000 600'
test.de. 1547 IN SOA ns1.test.de. dnsmaster.test.de. 2012090701 900 1000 6000 600
Il [:blank:]
la classe di caratteri comprende sia spazi che tabulazioni.