J'ai plus de 10000 fichiers csv dans un dossier et j'essaye de les fusionner par ligne en utilisant awk mais si j'exécute cette commande:
printf '%s\n' *.csv | xargs cat | awk 'FNR==1 && NR!=1{next;}{print}' *.csv > master.csv
J'obtiens les erreurs suivantes:
/ usr / bin / awk: liste d'arguments trop longue et printf: erreur d'écriture: tuyau cassé

1
Rby 31 août 2020 à 17:00

2 réponses

Meilleure réponse

Avec les parties printf et xargs, vous envoyez le contenu des fichiers csv dans awk, mais vous fournissez également les noms de fichiers à awk. Choisissez l'un ou l'autre: je suggère:

{ printf '%s\n' *.csv | xargs awk 'FNR==1 && NR!=1{next;}{print}'; } > master.csv
4
glenn jackman 31 août 2020 à 14:09

Si vos noms de fichiers ne contiennent pas de nouvelles lignes, vous pouvez faire:

printf '%s\n' *.csv | awk 'NR==FNR{ARGV[ARGC++]=$0; next} !c++ || FNR>1' -

Ou s'ils peuvent contenir des retours à la ligne, alors:

printf '%s\0' *.csv | awk -v RS='\0' 'NR==FNR{ARGV[ARGC++]=$0; next} !c++ || FNR>1' RS='\0' - RS='\n'

C'est-à-dire que awk lit la liste des noms de fichiers CSV en entrée plutôt que le shell en la passant à awk comme arguments. Cela fonctionnerait même si vous aviez des millions de fichiers CSV.

Par exemple, étant donné cette entrée:

$ head -n +50 file*.csv
==> file1.csv <==
Number
1
2

==> file2.csv <==
Number
10
11
12

Ce qui précède produirait cette sortie:

$ printf '%s\n' *.csv | awk 'NR==FNR{ARGV[ARGC++]=$0; next} !c++ || FNR>1' -
Number
1
2
10
11
12
2
Ed Morton 1 sept. 2020 à 14:01