web-dev-qa-db-fra.com

Place newline après chaque commande

Comment implémenter un retour chariot ou un retour à la ligne dans chaque commande awk d'un script Shell, de telle sorte que la sortie de chaque commande soit séparée de la suivante?

J'ai peut-être besoin de plus de précisions. J'ai deux commandes awk, listées ci-dessous:

awk {print $1, $2}, commande awk 1, sortie:

John Bender
Bohn Jender
Jen Bondher

awk '{print $3, $4}', command 2, output:

AGE 21
AGE 420
AGE 2345678909876543234567890876543234567890876543

Lorsqu'elles sont combinées dans un script Shell et exécutées avec ./<testscript>.sh <textfile>, la ligne de commande génère évidemment:

John Bender
Bohn Jender
Jen Bondher
AGE 21
AGE 420
AGE 2345678909876543234567890876543234567890876543

Parce que je veux la commande newline append PER awk, je veux que la sortie ressemble simplement à:

John Bender
Bohn Jender
Jen Bondher

AGE 21
AGE 420
AGE 2345678909876543234567890876543234567890876543

Les tentatives précédentes d’ajout de "\ n" ont abouti à:

John Bender

Bohn Jender

Jen Bondher

AGE 21

AGE 420

AGE 2345678909876543234567890876543234567890876543

..qui est certainement indésirable.

5
KMoy

Comme vous exécutez depuis un script Shell, ajoutez simplement echo après chaque commande awk, c'est-à-dire entre les commandes pour lesquelles vous souhaitez obtenir des sorties séparées. echo ajoute une nouvelle ligne. Par exemple:

awk '{print $1 $2}' file.txt
echo
awk '{print $3, $4}' file.txt

Réponse originale:

Ajoutez printf "\n" à la fin de chaque action awk{}.

printf "\n" imprimera une nouvelle ligne.

Exemple:

% awk '{print $1; printf "\n"}' <<<$'foo bar\nspam Egg'
foo

spam

7
heemayl

Juste parce qu'il est possible de le faire, voici quelles approches alternatives peuvent être adoptées.

ARGIND avec variables NR et FNR

Cette approche passe par le fichier deux fois et, au moment de la seconde lecture, elle imprime une nouvelle ligne obtenue à l'aide de quelques idées intéressantes.

  • Pour traiter le même fichier mais en extraire des informations différentes, le fichier est donné deux fois sur la ligne de commande.

  • Comment pouvons-nous distinguer lorsque nous parcourons le premier fichier (pour extraire les champs $ 1 et $ 2) et quand le second? Via l’utilisation de la variable ARGIND.

  • NR est le total des enregistrements traités jusqu'à présent, et FNR est le total des enregistrements traités dans le fichier en cours. Avec le premier fichier, ils sont identiques. Quand vont-ils différer? Quand on arrive au deuxième fichier. Pour le moment, nous devons imprimer une nouvelle ligne, mais en quelque sorte empêcher son impression pour d’autres valeurs où NR > FNR. Nous levons un drapeau (via une variable drapeau).

Exemple de sortie:

$ awk '!flag && NR>FNR {print "";flag=1} ARGIND==1{print $1,$2}ARGIND==2{print $3,$4}' data.txt data.txt                  
John Bender
Bohn Jender
Jen Bondher

AGE 21
AGE 420
AGE 2345678909876543234567890876543234567890876543

Utilisation de la clause END

Comme mentionné dans les commentaires sous heemayls, lorsque vous utilisez deux commandes awk distinctes, vous pouvez utiliser le bloc END pour imprimer quelque chose une fois le traitement du fichier terminé.

$ awk '{print $1,$2}END{print "\n"}' data.txt;  awk '{print $3,$4}' data.txt                                                          
John Bender
Bohn Jender
Jen Bondher


AGE 21
AGE 420
AGE 2345678909876543234567890876543234567890876543

Variation sur le bloc END avec des tableaux associatifs

Puisque votre bloc de 3 $ est fondamentalement la même chose encore et encore (chaîne "AGE"), vous n'avez pas à le stocker, mais vous pouvez stocker 4 $ dans un tableau associatif. Ensuite, dans le bloc FIN, vous pouvez parcourir les valeurs stockées après l’impression de nouvelle ligne.

$ awk '{print $1,$2;age[i++]=$4}END{print"";for(var in age) print "AGE",age[var]}' data.txt                                           
John Bender
Bohn Jender
Jen Bondher

AGE 21
AGE 420
AGE 2345678909876543234567890876543234567890876543
1