3 votes

Appliquer la commande awk à tous les fichiers d'un répertoire

Je suis nouveau en awk et je voudrais appliquer une commande awk simple à tous les fichiers d'un répertoire et obtenir le résultat pour chaque fichier séparément. Les fichiers sont délimités par des tabulations et j'ai juste besoin de faire la somme de chaque valeur dans la colonne 11 et d'imprimer le résultat séparément pour chaque fichier. J'ai essayé le code suivant mais il ne fonctionne pas.

for i in *;
do
awk -F '\t' '{sum += $11} END {print sum} "$i"'
done

Merci !

3voto

anubhava Points 172509

Vous pouvez utiliser ce gnu awk :

awk -F '\t' '{sum += $11} ENDFILE {print FILENAME ":", sum; sum=0}' *

ENDFILE sera exécuté à la fin du traitement pour chaque fichier où nous imprimons le nom du fichier et la somme.


Si vous n'avez pas gnu awk alors utilisez ceci :

awk -F '\t' 'FNR==1 {if (sum) print fn ":", sum; sum=0; fn=FILENAME} 
{sum += $11} END {print fn ":", sum}' *

2voto

Alex Shpilkin Points 230

Il semble que vous ayez une simple coquille dans votre citation shell ; cela devrait fonctionner :

for f in *; do awk -F '\t' '{sum += $11} END {print sum}' -- "$f"; done

(le -- n'est nécessaire que pour se protéger contre l'un des noms de fichiers commençant par un trait d'union ; une variable appelée i est généralement un nombre entier selon l'ancienne convention Fortran ; l'utiliser pour une chaîne de caractères est donc un peu pervers) ; ou encore

ls | while read -r f; do awk -F '\t' '{sum += $11} END {print sum}' -- "$f"; done

si vous voulez éviter le risque de vous heurter à la limite de la longueur de la ligne de commande (qui est grande mais finie sur les systèmes actuels), bien que cela soit cassé si vos noms de fichiers contiennent des sauts de ligne (pourquoi ? !..).

Si vous voulez tout faire en une seule invocation Awk, vous pouvez garder la trace des fichiers en utilisant FNR (nombre d'enregistrement dans le fichier) et FILENAME :

awk -F '\t' 'FNR==1 {if (f) print sum; sum = 0; f = FILENAME} END {print sum} {sum += $11}' -- *

ou alternativement (peut invoquer awk une ou plusieurs fois)

ls | xargs awk -F '\t' 'FNR==1 {if (f) print sum; sum = 0; f = FILENAME} END {print sum} {sum += $11}' --

avec les mêmes réserves que ci-dessus.

Vous pouvez vous prémunir contre les nouvelles lignes dans les noms de fichiers en abandonnant POSIX et en utilisant des GNUismes qui séparent les éléments avec des NULs (interdits dans les noms de fichiers) au lieu de nouvelles lignes (non interdites), mais à moins que votre script doive s'exécuter dans un environnement vraiment hostile, cela ne vaut probablement pas la peine.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X