Délimiter par l'espace mais ignorer l'espace barre oblique inverse

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 []

Je voudrais obtenir la première colonne de ce qui précède, mais le hic, c'est que je dois traiter \ (espace barre oblique inverse) comme une partie de la colonne, donc awk '{print $1}'devrait me donner

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
GypsyCosmonaut
la source
\ Est-il toujours traité comme un caractère d'échappement ou n'est-il que \ spécial? Par exemple, y a-t-il a\\ bun champ ou deux?
Gregory Nisbet
@GregoryNisbet que j'ai mis dans \ est pour le caractère d'échappement, pas les vraies données
GypsyCosmonaut
1
Si vos données contenaient une véritable barre oblique inverse, comment seraient-elles représentées?
Gregory Nisbet
@GregoryNisbet Bonne question. Parce que je l'ai remplacé uniquement [[:space:]]par \[[:space:]], les données d'origine n'ont pas été modifiées à leur place. Après avoir obtenu les données d'origine dans la première colonne délimitées uniquement par des espaces et non \[[:space:]], je remplacerais \[[:space:]]par [[:space:]]et je me retrouverais avec les données d'origine qui contiennent \.
GypsyCosmonaut

Réponses:

9

avec gnu awk ( gawk), vous pouvez utiliser des assertions de longueur nulle comme \<ou \>:

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

mais malheureusement pas les épanouies de perlou pcre(par exemple. (?<!\\), (?<=\w), etc.):

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

Vous pouvez remplacer \ espace par quelque chose d'autre et revenir ensuite.

sed 's/\\ /\\x20/g' data_file | awk '{ print $1; }' | sed 's/\\x20/\\ /g'
pLumo
la source
Uniquement avec sed: sed 's / \\ / \\ x20 / g; s /. * //; s / \\ x20 / \\ / g' data_file
ctac_
Ou, awk, en utilisant la valeur de variable SUBSEP par défaut de \034:awk '{gsub(/\\ /,SUBSEP,$0); val=$1; gsub(SUBSEP,"\\ ",val); print val}' file
glenn jackman
5

Avec GNU grepou compatible:

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

Ou avec ERE:

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

Cela traite \comme un opérateur de citation, pour les espaces comme un délimiteur, mais aussi pour lui-même. Autrement dit, en foo\\ barentrée, il revient foo\\.

Stéphane Chazelas
la source
4

Avec juste sed:

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

Ou plus court:

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

Cela (([^\]*\\ ){1,})?[^ ]*correspond:

  • [^\]*\\: tout ce qui n'est pas une barre oblique inverse qui se termine par une barre oblique inverse suivie d'un espace (notez que l' \intérieur de la classe de caractère n'a pas besoin d'être échappé, mais l'extérieur le fait).
  • ([^\]*\\ ){1,}: correspondance ci-dessus avec une ou plusieurs périodes d'occurrences.
  • (([^\]*\\ ){1,})?: ceci est facultatif lors de l'utilisation (...)?; nous pourrions également utiliser à la ([^\]*\\ ){0,}place ou ([^\]*\\ )*.
  • ((([^\]*\\ ){1,})?[^ ]*): correspond au-dessus de ce qui est facultatif suivi de tout ce qui n'est pas un espace et conservez comme correspondance de groupe avec \1comme référence arrière.
  • ((([^\]*\\ ){1,})?[^ ]*).*: correspond ci (...)- dessus et toute autre chose .*.

alors la pièce de rechange suffit d'imprimer ce \1qui est la sortie:

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нιη
la source