sed sostituisce tutte le schede e gli spazi con un unico spazio


23

Ho una stringa come la seguente:

test.de.          1547    IN      SOA     ns1.test.de. dnsmaster.test.de. 2012090701 900 1000 6000 600

ora voglio sostituire tutte le schede / gli spazi tra i record con un solo spazio in modo da poterlo usare facilmente cut -d " "

Ho provato quanto segue:

sed "s/[\t[:space:]]+/[:space:]/g"

e varie varianti ma non riusciva a farlo funzionare. Qualche idea?


Prova: sed -r -e "s / [\ t \] + / / g"
RJS

La tua opzione di cutsupporto -w?
Kondybas,

Risposte:


40

Uso 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é si tratta di un'abbreviazione per una classe di caratteri e il motore regex non saprebbe quale personaggio mettere lì.

La +deve essere sfuggito nel regex perché con motore regex di sed +è un personaggio normale, mentre \+è un metacarattere di 'uno o piu'. A pagina 86 di Mastering Regular Expressions , Jeffrey Friedl menziona in una nota a piè di pagina che ed e grep usavano parentesi sfuggite perché "Ken Thompson pensava che le espressioni regolari sarebbero state usate principalmente per lavorare con il codice C, dove la necessità di abbinare parentesi grezze sarebbe più comune del backreferencing ". Presumo che provasse la stessa cosa per il segno più, quindi la necessità di scappare per usarlo come metacarattere. È facile inciampare in questo.

In sed avrete bisogno di fuggire +, ?, |, (, e ). oppure usa -r per usare regex esteso (quindi sembra sed -r -e "s/[[:space:]]\+/ /g"osed -re "s/[[:space:]]\+/ /g"


Anche questo rimuove le schede? Puoi spiegare perché usi \+invece di solo +?
Zulakis,

Ok capisco. [[: space:]] è uguale a [\ t \ r \ n \ v \ f]. Ma si può spiegare il motivo per cui si utilizza\+
Zulakis

3
[[: space:]] è equivalente a '\ s', quindi la versione più corta è "s / \ s \ + / / g"
3molo,

2
Le espressioni regolari di base usano una barra rovesciata prima di un segno più quando usate per indicare "uno o più del carattere o gruppo precedente", fonte developer.apple.com/library/mac/#documentation/opensource/… .
3molo,

Ahh, ho capito! Non sapevo che esistessero diverse versioni di regex. Grazie
Zulakis,

6

È possibile utilizzare l' -sopzione ("squeeze") 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

La [:blank:]classe di caratteri comprende sia spazi che tabulazioni.


-2

Mi piace usare il seguente alias per bash. Basandosi su ciò che altri hanno scritto, usa sed per cercare e sostituire più spazi con un unico spazio. Questo aiuta a ottenere risultati coerenti dal taglio. Alla fine, lo eseguo ancora una volta per cambiare lo spazio in tab in modo che sia più facile da leggere.

alias ll='ls -lh | sed "s/ \+/ /g" | cut -f5,9 -d" " | sed "s/ /\t/g"'

Come risponde alla domanda?
Tonin,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.