Comment utiliser «:» comme séparateur de champ awk?

243

Étant donné la commande suivante:

echo "1: " | awk '/1/ -F ":" {print $1}'

pourquoi la sortie awk:

1: 
user173446
la source

Réponses:

382

"-F" est un argument de ligne de commande et non une syntaxe awk, essayez:

 echo "1: " | awk -F  ":" '/1/ {print $1}'
Jürgen Hötzel
la source
42
La question de Ignorant ici: la partie / 1 / est de dire à awk de ne traiter que les lignes (ou les enregistrements pour être plus précis) qui contiennent le numéro 1, n'est-ce pas?
rantsh
3
La syntaxe @rantsh Awk ressemble (pattern){action}. Si pattern(principalement une instruction conditionnelle) est vrai , actionest exécuté. Si patternn'est pas disponible, trueest implicite. Ici , le patternest selon /1/lequel est regex 1apparié dans l'enregistrement en cours$0
kvantour
62

Si vous voulez le faire par programme, vous pouvez utiliser la FSvariable:

echo "1: " | awk 'BEGIN { FS=":" } /1/ { print $1 }'

Notez que si vous le modifiez dans la boucle principale plutôt que dans la BEGINboucle, il prend effet pour la ligne suivante lue, car la ligne actuelle a déjà été divisée.

En pause jusqu'à nouvel ordre.
la source
35

Vous avez plusieurs façons de définir :comme séparateur:

awk -F: '{print $1}'

awk -v FS=: '{print $1}'

awk '{print $1}' FS=:

awk 'BEGIN{FS=":"} {print $1}'

Tous sont équivalents et pour un retourne 1pour un exemple d'entrée "1: 2: 3":

$ awk -F: '{print $1}' <<< "1:2:3"
1
$ awk -v FS=: '{print $1}' <<< "1:2:3"
1
$ awk '{print $1}' FS=: <<< "1:2:3"
1
$ awk 'BEGIN{FS=":"} {print $1}' <<< "1:2:3"
1
fedorqui 'SO arrête de nuire'
la source
quelle est la voie préférée? je suppose que l'exemple final avec la BEGINdéclaration serait le plus correct (étant cohérent avec la awksyntaxe globale ).
1
@randomware tous vont bien. J'ai tendance à utiliser BEGINsi j'utilise un fichier pour stocker le tout, tout -Fen étant pratique avec les monolignes.
fedorqui 'SO arrête de nuire'
1
Il faut dire qu'il existe des différences subtiles entre le troisième cas et tous les autres. Exemple: awk 'BEGIN{print split("foo:bar",a)}' FS=":" fileetawk 'BEGIN{FS=":"; print split("foo:bar",a)}' file
kvantour
@kvantour bon point. Je viens de demander à ce sujet dans Pourquoi le séparateur de champs est-il pris en compte différemment s'il est défini avant ou après l'expression? .
fedorqui 'SO arrête de nuire'
12

-Fest un argument en awksoi:

$echo "1: " | awk -F":" '/1/ {print $1}'
1
danben
la source
2
Pas besoin de citer deux points.
ceving
6

Vous pouvez également utiliser une expression régulière comme séparateur de champ, ce qui suit imprimera "barre" en utilisant une expression régulière pour définir le nombre "10" comme séparateur.

echo "foo 10 bar" | awk -F'[0-9][0-9]' '{print $2}'
Zlemini
la source
4

Pas besoin d'écrire autant. Mettez simplement votre séparateur de champs souhaité avec l'option -F dans la commande awk et le numéro de colonne que vous souhaitez imprimer séparé selon votre séparateur de champs mentionné.

echo "1: " | awk -F: '{print $1}'    
1

echo "1#2" | awk -F# '{print $1}'  
1
Bhavuk Taneja
la source
4

AWK fonctionne comme un interpréteur de texte qui va dans le sens des lignes pour tout le document et qui va dans le champ pour chaque ligne, donc $ 1, $ 2 .. $ n sont des références aux champs de chaque ligne ($ 1 est le premier champ, $ 2 est le deuxième champ et ainsi de suite ...). Vous pouvez définir un séparateur de champ en utilisant le commutateur "-F" sous la ligne de commande ou entre deux crochets avec "FS = ...". Considérez maintenant la réponse de "JUERGEN":

echo "1: " | awk -F  ":" '/1/ {print $1}'

Au-dessus des limites de champ sont définies par ":" donc nous avons deux champs $ 1 qui est "1" et $ 2 qui EST l'espace vide. Après, vient l'expression régulière "/ 1 /" qui demande au filtre de sortir le premier champ uniquement lorsque l'interprète tombe sur une ligne contenant une telle expression (je veux dire 1); La sortie de la commande "echo" est une ligne qui contient "1" pour que le filtre fonctionne ...

Lorsque vous traitez l'exemple suivant:

echo "1: " | awk '/1/ -F ":" {print $1}'

La syntaxe est désordonnée et l' interprète a choisi d'ignorer la partie F ":" et passe au séparateur de champs par défaut qui est l'espace vide produisant ainsi "1:" comme premier champ et il n'y aura pas de deuxième champ!

La réponse de JUERGEN contient la bonne syntaxe ...

jihed gasmi
la source
3

Ou vous pouvez utiliser:

echo "1: " | awk  '/1/{print $1-":"}' 

C'est une équation vraiment drôle.

Vonton
la source
1
qu'est-ce que cela /1/signifie?
Trouvez un motif. Dans ce cas "1"
José Dias