Fusion de plusieurs fichiers CSV sans fusionner l'en-tête


21

J'ai besoin de fusionner plusieurs fichiers .CSV (à l'aide de la catcommande) mais sans copier l'en-tête de chaque fichier.

Quelle est la meilleure façon d'accomplir cette tâche?

Réponses:


32

Vous aurez besoin de plus que la catcommande, comme décrit ici :

Disons que vous avez 3 fichiers CSV: file1.csv, file2.csvet file3.csvet que vous voulez les rejoindre à bigfile.csvet votre tête est toujours (seulement) la première ligne, puis utiliser

soit (conserver l'en-tête du premier fichier "file1.csv"):

cat file1.csv <(tail +2 file2.csv) <(tail +2 file3.csv) > bigfile.csv

ou (supprimer l'en-tête de tous les fichiers dont le nom commence par "fichier"):

awk 'FNR > 1' file*.csv > bigfile.csv

4
J'ai trouvé cela à la recherche d'une réponse Linux générique, mais dans mon cas, cela n'a pas fonctionné exactement. Il ignorerait silencieusement file1.csv. J'avais besoin de cat ce fichier. cat <(cat file1.csv) <(tail +2 file2.csv) <(tail +2 file3.csv) > bigfile.csv
Lelon

Je reçois tail + 2: commande introuvable lorsque j'ai utilisé cat <file1.csv <(tail +2 file2.csv) <(tail +2 file3.csv)> méthode

@ user64636, il devrait y avoir un caractère espace entre la queue et +2
nohillside

en fait je devais utiliser tail -n+2, ça tail +2ne marcherait pas
Matthieu Napoli

12

Je suis d'accord avec la réponse du haut mais je suggère de l'étendre avec le scénario suivant (car je ne peux pas commenter):

Si vous voulez que le fichier de sortie contienne (une fois) l'en-tête, le script correct est:

awk '(NR == 1) || (FNR > 1)' file*.csv > bigfile.csv

FNR représente le numéro de l'enregistrement traité dans un seul fichier. Et NR le représente globalement, donc la première ligne est acceptée et les autres sont ignorées comme auparavant.


6

Vous pouvez également utiliser une commande de groupe ( { ; }) au lieu de la substitution de processus ( <()):

{ head -n1 file1.csv; for f in file*.csv; do tail -n+2 "$f"; done; } > new.csv

Il fonctionne également avec les fins de ligne CRLF tant que les fichiers se terminent par une ligne vide ( \r\n).

Les versions numériques de la tête et de la queue ont été rendues obsolètes par POSIX 1003.1-2001 et entraînent des avertissements dans certains environnements.


2

Nécessaire pour concaténer deux grands CSV avec des colonnes identiques dans un CSV plus grand pour le script de segmentation (les données n'ont pas d'ID unique).

Première prise d'en-tête sur la seconde csv

awk 'FNR > 1' file2.csv > file2_noheading.csv

Ensuite, concaténé via ce qui suit

cat file1.csv file2_noheading.csv > newfile.csv

1

L'utilisation de la séquence de commandes ci-dessus a donné un fichier ressemblant à ceci:

header,of,csv1
contents,of,csv1
==> csv2.csv

contents,of,csv2

Pour en faire un CSV correct, avec une ligne d'en-tête et toutes les valeurs pertinentes, j'ai utilisé l' sedincantation suivante ...sed -ie "/^$/d;/^==>/d" bigfile.csv


0

Solution plus simple si vous avez une tonne de fichiers:

awk 'FNR > 1' *.csv > merged.csv

Revenez simplement pour modifier le gros fichier et ajoutez l'en-tête.


En quoi votre réponse est-elle différente de ce que tout était prêt présenté par iolsmit en 2013 awk 'FNR > 1' file*.csv > bigfile.csv? Ce n'est pas!
user3439894

Re: en quoi est-ce différent? C'est une réponse plus concise et celle que j'ai copiée et collée, au moins:) Obtient mon vote positif
Rick Davies

C'est une bonne réponse, car vous n'avez pas besoin de tous les fichiers pour commencerfile
big_smile
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.