Ho bisogno di unire più file .CSV (usando il comando cat
) ma senza copiare l'intestazione per ogni file.
Qual è il modo migliore per eseguire questa attività?
Avrai bisogno di più del comando cat
, come descritto qui :
Supponiamo di avere 3 file CSV: file1.csv
, file2.csv
e file3.csv
e vuoi unirli a bigfile.csv
e l'intestazione è sempre (solo) la prima riga, quindi usa
(mantenere l'intestazione dal primo file):
cat < file1.csv <(tail +2 file2.csv) <(tail +2 file3.csv) > bigfile.csv
o (rimuovi intestazione da tutti i file i cui nomi iniziano con "file"):
awk 'FNR > 1' file*.csv > bigfile.csv
Potresti anche utilizzare un comando di gruppo ( { ; }
) invece della sostituzione di processo ( <()
):
{ head -n1 file1.csv; for f in file*.csv; do tail -n+2 "$f"; done; } > new.csv
Funziona anche con terminazioni di riga CRLF a condizione che i file terminino con una riga vuota ( \r\n
).
Le versioni solo numero di testa e coda sono state rese obsolete da POSIX 1003.1-2001 e provocano avvisi in alcuni ambienti.
Sono d'accordo con la risposta migliore ma suggerisco di estenderla con il seguente scenario (non posso commentare):
Se vuoi 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 globalmente, quindi la prima riga viene accettata e il resto viene ignorato come prima.
Necessario per concatenare due CSV di grandi dimensioni con colonne identiche in CSV più grande per lo script chunking (i dati non hanno ID univoci).
Prima ha estratto l'intestazione dal secondo csv
awk 'FNR > 1' file2.csv > file2_noheading.csv
Successivamente, concatenato tramite il seguente
cat file1.csv file2_noheading.csv > newfile.csv
L'utilizzo della sequenza di comandi sopra riportata ha prodotto un file simile a questo:
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 rilevanti, ho impiegato il seguente sed
incantation ... sed -ie "/^$/d;/^==>/d" bigfile.csv
Soluzione più semplice se hai un sacco di file:
awk 'FNR > 1' *.csv > merged.csv
Torna indietro per modificare il file grande e aggiungere nuovamente l'intestazione.