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?

Dranian
la source

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
iolsmit
la source
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.

Marek Grác
la source
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.

Lri
la source
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
mcconnelljk
la source
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

hd1
la source
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.

Brian
la source
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