36 votos

Combinando varios archivos CSV sin fusionar la cabecera

Necesito fusionar varios archivos .CSV (usando el comando cat) pero sin copiar el encabezado de cada archivo.

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

45voto

penkoad Puntos 41

Necesitarás algo más que el comando cat, como se describe aquí:

Supongamos que tienes 3 archivos CSV: file1.csv, file2.csv y file3.csv y quieres unirlos en bigfile.csv y tu encabezado siempre es (solo) la primera línea, entonces usa

ya sea (mantener encabezado del primer archivo "file1.csv"):

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

o (eliminar encabezado de todos los archivos cuyos nombres empiezan con "file"):

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

4 votos

Encontré esto buscando una respuesta genérica de Linux, pero en mi caso esto no funcionó exactamente. Ignoraría silenciosamente el archivo1.csv. Necesitaba concatenar ese archivo. cat <(cat file1.csv) <(tail +2 file2.csv) <(tail +2 file3.csv) > bigfile.csv

0 votos

En realidad tuve que usar tail -n+2, tail +2 no funcionaría

35voto

Marek Grác Puntos 251

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

Si quieres que el archivo de salida contenga encabezado (una sola 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, así que la primera línea es aceptada y el resto se ignoran como antes.

0 votos

Sigo volviendo a esta respuesta cada vez que me encuentro con una fusión de archivos CSV en la línea de comandos, que requiere mantener solo la cabecera de un archivo.

0 votos

¿Qué pasa si tenemos que eliminar las originales..?

9voto

También puedes utilizar un comando de grupo ({ ; }) en lugar de la sustitución de procesos (<()):

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

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

Las versiones solo de números de head y tail fueron descontinuadas por POSIX 1003.1-2001, y resultan en advertencias en algunos entornos.

2voto

mcconnelljk Puntos 21

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

Primero saqué el encabezado del segundo CSV

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

Luego, concatené utilizando lo siguiente

cat file1.csv file2_noheading.csv > newfile.csv

1voto

hd1 Puntos 101

Usar la secuencia de comandos anterior resultó en un archivo que se veía así:

encabezado,de,csv1
contenido,de,csv1
==> csv2.csv

contenido,de,csv2

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

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X