sed reemplazar todas las pestañas y espacios con un solo espacio

23

Tengo una cadena como la siguiente:

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

ahora quiero reemplazar todas las pestañas / espacios entre los registros con un solo espacio para poder usarlo fácilmente con cut -d " "

Intenté lo siguiente:

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

y varias variaciones pero no pude hacerlo funcionar. ¿Algunas ideas?

Zulakis
fuente
Prueba: sed -r -e "s / [\ t \] + / / g"
RJS
¿Su opción de cutapoyos -w?
Kondybas

Respuestas:

40

Utilizar sed -e "s/[[:space:]]\+/ /g"

Aquí hay una explicación:

[   # 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).

Para su reemplazo, solo desea insertar un espacio. [:space:]no funcionará allí ya que es una abreviatura para una clase de personaje y el motor de expresiones regulares no sabría qué personaje poner allí.

Se +debe escapar en la expresión regular porque con el motor de expresión regular de sed +es un carácter normal, mientras que \+es un metacarácter para 'uno o más'. En la página 86 de Mastering Regular Expressions , Jeffrey Friedl menciona en una nota al pie de página que ed y grep usaron paréntesis escapados porque "Ken Thompson sintió que las expresiones regulares se usarían principalmente con el código C, donde la necesidad de unir paréntesis sin procesar sería más común que la referencia inversa ". Supongo que él sentía lo mismo por el signo más, de ahí la necesidad de escapar de él para usarlo como metacarácter. Es fácil dejarse engañar por esto.

En sed que necesita para escapar +, ?, |, (, y ). o use -r para usar expresiones regulares extendidas (entonces parece sed -r -e "s/[[:space:]]\+/ /g"osed -re "s/[[:space:]]\+/ /g"

Estrella de mar
fuente
¿Esto también elimina las pestañas? ¿Puedes explicar por qué lo usas en \+lugar de solo +?
Zulakis
De acuerdo, lo entiendo. [[: espacio:]] es igual a [\ t \ r \ n \ v \ f]. Pero, ¿puede explicar por qué lo usa?\+
Zulakis
3
[[: space:]] es equivalente a '\ s', por lo que la versión más corta es "s / \ s \ + / / g"
3molo
2
Las expresiones regulares básicas usan una barra diagonal inversa antes de un signo más cuando se usan para significar "uno o más del carácter o grupo anterior", fuente developer.apple.com/library/mac/#documentation/opensource/… .
3molo
Ahh, entiendo! No sabía que había diferentes versiones de expresiones regulares. Gracias
Zulakis
6

Puede usar la -sopción ("apretar") de 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:]clase de caracteres comprende espacios y tabulaciones.

Benjamin W.
fuente
-2

Me gusta usar el siguiente alias para bash. Basándose en lo que otros escribieron, use sed para buscar y reemplazar múltiples espacios con un solo espacio. Esto ayuda a obtener resultados consistentes del corte. Al final, lo ejecuté una vez más para cambiar el espacio a la pestaña para que sea más fácil de leer.

alias ll='ls -lh | sed "s/ \+/ /g" | cut -f5,9 -d" " | sed "s/ /\t/g"'
CNS Security miked
fuente
¿Cómo responde esto a la pregunta?
Tonin