Fusionar múltiples archivos CSV sin fusionar el encabezado

21

Necesito fusionar múltiples archivos .CSV (usando el catcomando) pero sin copiar el encabezado de cada archivo.

¿Cuál es la mejor manera de lograr esta tarea?

Dranian
fuente

Respuestas:

32

Necesitará más que el catcomando, como se describe aquí :

Digamos que tiene 3 archivos CSV: file1.csv, file2.csv, y file3.csvy desea unirse a ellos para bigfile.csvy su cabecera es siempre (sólo) la primera línea, a continuación, el uso

bien (mantener el encabezado del primer archivo "file1.csv"):

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

o (elimine el encabezado de todos los archivos cuyos nombres comienzan con "archivo"):

awk 'FNR > 1' file*.csv > bigfile.csv
Iolsmit
fuente
44
Encontré esto buscando una respuesta genérica de Linux, pero en mi caso esto no funcionó exactamente. Silenciosamente ignoraría file1.csv. Necesitaba atrapar ese archivo. cat <(cat file1.csv) <(tail +2 file2.csv) <(tail +2 file3.csv) > bigfile.csv
Lelon
Estoy obteniendo tail + 2: comando no encontrado cuando utilicé cat <file1.csv <(tail +2 file2.csv) <(tail +2 file3.csv)> método
@ user64636 debe haber un espacio entre la cola y +2
nohillside
De hecho, tuve que usar tail -n+2, tail +2no funcionaría
Matthieu Napoli
12

Estoy de acuerdo con la respuesta principal, pero sugiero extenderla con el siguiente escenario (ya que no puedo comentar):

Si desea que el archivo de salida contenga encabezado (una vez), el script correcto es:

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

FNR representa el número del registro procesado en un solo archivo. Y NR lo representa globalmente, por lo que se acepta la primera línea y el resto se ignora como antes.

Marek Grác
fuente
6

También puede usar un comando de grupo ( { ; }) en lugar de la sustitución de proceso ( <()):

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

También funciona con terminaciones de línea CRLF siempre que los archivos terminen con una línea vacía ( \r\n).

POSIX 1003.1-2001 dejó obsoletas las versiones de solo cabeza y cola, y generan advertencias en algunos entornos.

Lri
fuente
2

Necesario para concatenar dos CSV grandes con columnas idénticas en CSV más grandes para la secuencia de comandos de fragmentación (los datos no tienen identificadores únicos).

Primero sacó el encabezado del segundo csv

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

A continuación, concatenado a través de lo siguiente

cat file1.csv file2_noheading.csv > newfile.csv
mcconnelljk
fuente
1

El uso de la secuencia de comandos anterior dio como resultado un archivo similar a este:

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

contents,of,csv2

Para convertirlo en un CSV adecuado, con una línea de encabezado y todos los valores relevantes, empleé el siguiente sedencantamiento ...sed -ie "/^$/d;/^==>/d" bigfile.csv

hd1
fuente
0

Solución más fácil si tiene una tonelada de archivos:

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

Simplemente regrese para editar el archivo grande y agregue el encabezado nuevamente.

brian
fuente
¿En qué se diferencia su respuesta de lo que fue presentado por iolsmit en 2013 awk 'FNR > 1' file*.csv > bigfile.csv? ¡No es!
user3439894
Re: ¿cómo es diferente? Es una respuesta más concisa y la que copié y pegué, al menos:) Obtiene mi voto a favor
Rick Davies
Esta es una buena respuesta, porque no necesita todos los archivos para comenzarfile
big_smile