2012-05-24 6 views
10

Estoy intentando, usando bash, fusionar el contenido de una lista de archivos (más de 1K) en un archivo grande.shell - cat - fusiona contenido de archivos en un gran archivo

He intentado el siguiente comando cat:

cat * >> bigfile.txt 

sin embargo lo que este comando hace es combinar todo, incluido también las cosas ya fusionadas.

p. Ej. file1.txt

content1 

file2.txt

content2 

file3.txt

content3 

file4.txt

content4 

bigfile.txt

content1 
content2 
content3 
content2 
content3 
content4 
content2 

pero me gustaría simplemente

content1 
content2 
content3 
content4 

dentro del archivo .txt

La otra forma sería cat file1.txt file2.txt ... y así sucesivamente ... pero no puedo hacerlo por más de archivos 1k!

¡Gracias por su apoyo!

Respuesta

18

El problema es que pone bigfile en el mismo directorio, por lo que es parte de *. Así que algo como

cat dir/* > bigfile 

sólo debe trabajar como quiera que, con sus fileN.txt archivos ubicados en dir/

+1

... o 'cat *>/tmp/bigfile; mv/tmp/bigfile .'. – tripleee

+0

Creo que fabioln está incluyendo intencionalmente 'bigfile.txt' en la entrada; él quiere agregar al archivo de los diversos 'archivo * .txt', pero elimina duplicados al mismo tiempo. – chepner

+0

Gracias chicos. ¡Sí, ese era el problema! Puse el bigfile en el mismo directorio ... así que usé el comando que me diste (cat dir/*> bigfile). Solo otra pregunta: ¿por qué pones simplemente> en lugar de >> ¿es lo mismo? ¡Gracias! – fabioln79

-3

Probar:

cat `ls -1 *` >> bigfile.txt 

no tengo una máquina Unix a mano en el momento para probarlo primero.

+2

-1 Esto no resuelve nada, y presenta algunos problemas nuevos. ¡No use 'ls' cuando el comodín ya se expande a los archivos que desea! No utilice nombres de archivo sin comillas (el resultado de los backticks) porque se rompe si los nombres de archivo contienen espacios en blanco. – tripleee

+0

Estaba pensando en un ciclo cuando escribí eso, pero no salió de mi cabeza correctamente. Me gusta más la respuesta de Barton de todos modos. – JerseyMike

4

Al volver a leer su pregunta, parece que desea agregar datos a bigfile.txt, pero sin agregar duplicados. Vas a tener que pasar todo a través de sort -u para filtrar duplicados:

sort -u * -o bigfile.txt 

La opción -o para ordenar permite incluir de forma segura el contenido de bigfile.txt en la entrada para ordenar antes de que el archivo se sobrescribe con la salida.

EDIT: Suponiendo bigfile.txt se ordena, se puede tratar de un proceso de dos etapas:

sort -u file*.txt | sort -um - bigfile.txt -o bigfile.txt 

Primero ordenar los archivos de entrada, la eliminación de duplicados.Transmitimos ese resultado a otro proceso sort -u, este usando la opción -m que también dice sort para unir dos archivos previamente ordenados. Los dos archivos que fusionaremos son - (entrada estándar, la transmisión proviene del primer sort) y bigfile.txt. Nuevamente usamos la opción -o para permitirnos escribir la salida nuevamente en bigfile.txt después de haberla leído como entrada.

+0

He modificado la respuesta para permitir que los nuevos datos se combinen en 'bigfile.txt' de tal forma que permanezca ordenada sin duplicados. Creo que esto es lo mejor que puede hacer sin cambiar a un formato más estructurado (como una base de datos). – chepner

4

Usted puede guardar el archivo de salida en el mismo directorio, sólo hay que ser un poco más sofisticado que *:

shopt -s extglob 
cat !(bigfile.txt) > bigfile.txt 
+0

Gracias. Tengo una pregunta relacionada con este comando: el directorio que contiene el archivo tiene un tamaño de 557 GB, sin embargo, el bigfile creado tiene un tamaño de 495. No sé cómo explicar esto. ¿Estoy haciendo algo mal? ¡Gracias! – fabioln79

+0

@ fabioln79 Con la cantidad de información proporcionada, sospeche que esto podría deberse al espacio utilizado en realidad frente al tamaño del Bloque (Lectura en este último) – user66001

2

La otra forma sería gato file2.txt file1.txt .. . y así sucesivamente ... ¡pero no puedo hacerlo por más de 1k archivos!

Esto es lo que xargs es para:

find . -maxdepth 1 -type f -name "file*.txt" -print0 | xargs -0 cat > bigfile.txt 
+0

¿xargs ejecuta el comando para * cada * argumento? Si es así, ¿debería usar '>>' en lugar de '>'? Estoy pensando que cuando termine, bigfile.txt solo contendrá el contenido del último archivo que se le pasó. – JerseyMike

+1

xargs ejecuta el comando una vez para todos los argumentos, no necesita usar ''>>''. –

+0

Gracias por la aclaración. La página de manual no me fue muy clara. – JerseyMike

1

Esta es una vieja pregunta, pero todavía me voy a dar otro enfoque con xargs lista

  1. los archivos que desea a concat

    ls | grep [patrón]> lista de archivos

  2. revisión de sus archivos están en el orden correcto, con vi o cat. Si utiliza un sufijo (1, 2, 3, ..., N), esto debería haber ningún problema

  3. Crear el archivo final

    lista de archivos cat | xargs cat >> [fichero final]

  4. Retire la lista de archivos

    rm -f lista de archivos

Esperamos que esto ayude a nadie

Cuestiones relacionadas