Delimitar por espacio pero ignorar espacio de barra invertida

8
5678 []
testing,\ group []
[testing []
ip\ 5.6.7.8 []
launch-wizard-1 0.0.0.0/0
456dlkjfa []
1.2.3.4 []
test 1.2.3.4/32 4.3.2.0/23 4.3.2.0/23
default 4.3.2.0/23 4.3.2.0/23
launch-wizard-2 0.0.0.0/0
launch-wizard-3 0.0.0.0/0
2.3.4.5/32 []

Me gustaría obtener la primera columna de lo anterior, pero el problema es que necesito tratar \ (espacio de barra invertida) como parte de la columna, así que awk '{print $1}'debería darme

5678
testing,\ group
[testing
ip\ 5.6.7.8
launch-wizard-1
456dlkjfa
1.2.3.4
test
default
launch-wizard-2
launch-wizard-3
2.3.4.5/32
GitanoCosmonauta
fuente
¿Siempre se trata como un personaje de escape o solo es \ especial? Por ejemplo, ¿hay a\\ buno o dos campos?
Gregory Nisbet
@GregoryNisbet que he puesto \ es para el personaje de escape, no los datos reales
GypsyCosmonaut
1
Si sus datos contienen una barra invertida real, ¿cómo se representaría?
Gregory Nisbet
@GregoryNisbet Buena pregunta. Debido a que reemplacé solo [[:space:]]con \[[:space:]], los datos originales han sido \ intactos en su lugar. Después de obtener los datos originales en la primera columna delimitados solo por espacios y no \[[:space:]], estaría reemplazando \[[:space:]]con [[:space:]]y me quedaría con los datos originales nuevamente que tienen \.
GypsyCosmonaut

Respuestas:

9

con gnu awk ( gawk) puedes usar algunas aserciones de longitud cero como \<o \>:

$ echo 'a\ b c' | gawk 'BEGIN{FS="\\> +"} {print $1}'
a\ b

pero por desgracia no los que en toda regla de perlo pcre(por ejemplo. (?<!\\), (?<=\w), etc):

$ echo 'a\ b, c' | perl -nle '@a=split /(?<!\\)\s+/, $_; print $a[0]'
a\ b,
Mosvy
fuente
5

Podrías sustituir \ space con otra cosa y volver nuevamente después.

sed 's/\\ /\\x20/g' data_file | awk '{ print $1; }' | sed 's/\\x20/\\ /g'
pLumo
fuente
Solo con sed: sed 's / \\ / \\ x20 / g; s /. * //; s / \\ x20 / \\ / g' data_file
ctac_
O, awk, utilizando el valor predeterminado de la variable SUBSEP de \034:awk '{gsub(/\\ /,SUBSEP,$0); val=$1; gsub(SUBSEP,"\\ ",val); print val}' file
glenn jackman el
5

Con GNU grepo compatible:

grep -Po '^(\\.|\S)*'

O con ERE:

grep -Eo '^(\\.|[^\[:space:]])*'

Eso se trata \como un operador de comillas, para los espacios en blanco como un delimitador, pero también para sí mismo. Es decir, en la foo\\ barentrada, vuelve foo\\.

Stéphane Chazelas
fuente
4

Con solo sed:

sed -r 's/^((([^\]*\\ ){1,})?[^ ]*).*/\1/' infile

O más corto:

sed -r 's/^(([^\]*\\ )*[^ ]*).*/\1/' infile

Esto (([^\]*\\ ){1,})?[^ ]*coincide:

  • [^\]*\\: cualquier cosa que no sea una barra diagonal inversa que termine con una barra diagonal inversa seguida de un espacio (tenga \en cuenta que no se requiere que se escape la clase de carácter interno, pero sí lo hace fuera).
  • ([^\]*\\ ){1,}: coincidencia anterior con una o más veces de ocurrencias.
  • (([^\]*\\ ){1,})?: esto es opcional cuando se usa (...)?; podríamos usar ([^\]*\\ ){0,}en su lugar también o ([^\]*\\ )*.
  • ((([^\]*\\ ){1,})?[^ ]*): coincide con lo anterior, que es opcional, seguido de cualquier cosa que no sea un espacio y mantenga como coincidencia de grupo con \1su referencia posterior.
  • ((([^\]*\\ ){1,})?[^ ]*).*: coincidencias anteriores (...)y cualquier otra cosa .*.

entonces es parte de reemplazo solo imprima \1cuál es la salida:

5678
testing,\ group
[testing
ip\ 5.6.7.8
launch-wizard-1
456dlkjfa
1.2.3.4
test
default
launch-wizard-2
launch-wizard-3
2.3.4.5/32
αғsнιη
fuente