web-dev-qa-db-fra.com

awk: achemine la sortie de l'impression (conditionnelle) vers gzip

considérez ce fichier:

#!/usr/bin/env bash
cat > example_file.txt <<EOL
group, value
1, 3.21
1, 3.42
1, 3.5
2, 4.1
2, 4.2
EOL

dans le script suivant, je regroupe les lignes de ce fichier en fonction des valeurs de la première colonne (les valeurs de la première colonne sont déjà triées) et j'imprime chaque groupe dans un fichier txt individuel:

var=$(echo 'example_file.txt')
var2=$(echo $var|sed "s/.txt//g")
mkdir -p output
cat $var | awk -v varn="$var2" -F, 'FNR == 1 {header = $0;next} !seen[$1]++ { print header > ("output/"varn"_"$1".txt") }{print > ("output/"varn"_"$1".txt");}'

question

Comment imprimer le résultat dans un flux compressé "output/"varn"_"$1".gz" (au lieu d'un fichier txt non compressé "output/"varn"_"$1".txt")?

(Ainsi, le résultat souhaité est identique à celui que le script produit maintenant, je souhaite seulement que les fichiers générés soient compressés et sauvegardés dans .txt.gz au lieu de fichiers au format texte brut comme le code le fait maintenant).

(J'ai essayé d'utiliser gzip > à l'intérieur des blocs {print} mais en vain :(

(PS: je suis un peu un peu stupide et la question peut donc être vraiment stupide.)

3
user2413

Vous pouvez diriger les commandes dans GNU print de awk. De le GNU awk manual :

print items | command

Il est possible d'envoyer la sortie à un autre programme via un canal plutôt que dans un fichier. Cette redirection ouvre un canal de commande et écrit les valeurs des éléments de ce canal dans un autre processus créé pour exécuter la commande.

L'argument de redirection command est en fait une expression awk. Sa valeur est convertie en une chaîne dont le contenu indique à la commande Shell à exécuter. Par exemple, ce qui suit produit deux fichiers, une liste non triée de noms de personnes et une liste triée par ordre alphabétique inverse:

awk '{ print $1 > "names.unsorted"
       command = "sort -r > names.sorted"
       print $1 | command }' mail-list

Alors:

awk -v varn="$var2" -F, 'FNR == 1 {header = $0;next}
  !seen[$1]++ { print header | "gzip > "output/"varn"_"$1".gz" }
  {print | "gzip > output/"varn"_"$1".gz";}'

Par exemple:

% echo 1 2 | awk '{print $2 | "gzip > "$1".gz"}'
% zcat 1.gz 
2
6
muru