Unione di più file CSV senza unire l'intestazione


21

Devo unire più file .CSV (usando il catcomando) ma senza copiare l'intestazione per ogni file.

Qual è il modo migliore per svolgere questo compito?

Risposte:


32

Avrai bisogno di più del catcomando, come descritto qui :

Diciamo che avete 3 CSV-files: file1.csv, file2.csv, e file3.csve si desidera unirsi a loro per bigfile.csve l'intestazione è sempre, quindi l'uso (solo) la prima linea

sia (mantenere intestazione dal primo file "file1.csv"):

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

oppure (rimuovere l'intestazione da tutti i file i cui nomi iniziano con "file"):

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

4
Ho trovato questo alla ricerca di una risposta linux generica, ma nel mio caso non ha funzionato esattamente. Ignorerebbe silenziosamente file1.csv. Avevo bisogno di cat quel file. cat <(cat file1.csv) <(tail +2 file2.csv) <(tail +2 file3.csv) > bigfile.csv
Lelon,

Ricevo tail + 2: comando non trovato quando ho usato cat <file1.csv <(tail +2 file2.csv) <(tail +2 file3.csv)> metodo

@ user64636 dovrebbe esserci un carattere spaziale tra coda e +2
nohillside

in realtà dovevo usare tail -n+2, tail +2non avrebbe funzionato
Matthieu Napoli

12

Sono d'accordo con la risposta principale ma suggerisco di estenderlo con il seguente scenario (in quanto non posso commentare):

Se si desidera che il file di output contenga l'intestazione (una volta) lo script corretto è:

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

FNR rappresenta il numero del record elaborato in un singolo file. E NR lo rappresenta a livello globale, quindi la prima riga viene accettata e il resto viene ignorato come prima.


6

È inoltre possibile utilizzare un comando di gruppo ( { ; }) anziché la sostituzione di processo ( <()):

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

Funziona anche con i finali di riga CRLF purché i file terminino con una riga vuota ( \r\n).

Le versioni solo numeriche di testa e coda sono state rese obsolete da POSIX 1003.1-2001 e generano avvisi in alcuni ambienti.


2

Necessario concatenare due CSV di grandi dimensioni con colonne identiche in CSV più grandi per lo script di suddivisione (i dati non hanno ID univoci).

In primo luogo ha preso l'intestazione dal secondo CSV

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

Successivamente, concatenato tramite quanto segue

cat file1.csv file2_noheading.csv > newfile.csv

1

L'uso della sequenza di comandi sopra ha comportato un file simile al seguente:

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

contents,of,csv2

Per renderlo un CSV corretto, con una riga di intestazione e tutti i valori pertinenti, ho utilizzato il seguente sedincantesimo ...sed -ie "/^$/d;/^==>/d" bigfile.csv


0

Soluzione più semplice se hai un sacco di file:

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

Torna indietro per modificare il file di grandi dimensioni e aggiungere nuovamente l'intestazione.


In che modo la tua risposta è diversa da quella che era stata già presentata da iolsmit nel 2013 awk 'FNR > 1' file*.csv > bigfile.csv? Non è!
user3439894

Ri: come è diverso? È una risposta più concisa e quella che ho copiato e incollato, almeno:) Ottiene il mio voto
Rick Davies,

Questa è una buona risposta, perché non hai bisogno di tutti i file per iniziarefile
big_smile,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.