Dividir un archivo en dos archivos en una línea dada

12

Estoy buscando una manera en Unix para dividir un archivo en dos archivos en un número de línea dado.

split -l 100 file_nameestá cerca de lo que estoy buscando, pero este comando crea varios archivos, cada uno de 100 líneas. Estoy buscando un comando para dividir un archivo en dos archivos en un número de línea dado. ¿Hay alguna manera de hacer esto en Unix?

Tortuga
fuente

Respuestas:

12

Una solución un poco más estricta:

(head -100 > f1.txt; cat > f2.txt) < input.txt
Rubens
fuente
1
Buena solución Sin contar wcantes y el archivo de entrada todavía se procesa solo una vez, como con la awksolución.
Dubu
2
Hay una pequeña posibilidad de que headlea más de solo 100 líneas para encontrar las primeras 100 líneas a las que se enviará f1.txt; esos bytes adicionales no serán vistos por cat.
chepner
Esto es muy lento
sdaffa23fdsf
12

Use awk, por lo que necesita hacer una sola pasada a través del archivo de entrada. Lo siguiente asume que desea las primeras 122 líneas en el primer archivo y el resto en el segundo.

awk 'NR < 123 { print >> "top_file"; next } {print >> "bottom_file" }' file_name
chepner
fuente
Esto merece un visto bueno. Si desea dividir un archivo de X a Y, este es el más fácil.
Glenn Plas
Esta es la solución más fácil de entender. Funcionó de maravilla ... y me hace pensar que debería sacudir el polvo de mi libro O'Reilly Sed & Awk que he tenido desde 1999 más o menos, la sección sed está bien leída, la sección awk no tanto.
Michael
Esto es mejor que la solución exceptuada por la razón que @chepner mencionó en los comentarios. Perderá caracteres en el archivo 'f2.txt'. Esta solución es precisa y eficiente. awk ftw.
Goran
7

Puede usar heady tailpara obtener ambas partes:

head -n K file_name > top_file
tail -n L file_name > bottom_file

donde Kes el número de línea y Les el número de líneas desde la parte inferior (número total de líneas - K).

(puede obtener el número total de líneas usando wc -l file_name).

jh314
fuente
5

Puede usar csplit(si está disponible) para hacerlo:

csplit file N+1

dividirá el archivo en dos partes, una parte hasta (e incluyendo) el número de línea Ny la otra parte desde el número de línea N+1hasta la última línea.
Si desea dividir hasta (pero sin incluir) el número de línea N:

csplit file N
don_crissti
fuente
Eso es genial! Gracias, resolvió el problema perfectamente para mí.
Zertrin
El mejor rendimiento para dividir archivos de 20GB en pedazos.
dr0i
@ dr0i: no es de extrañar, csplitestá optimizado para este trabajo.
don_crissti
Dividiendo un archivo de 200 millones de líneas obtuve "memoria agotada" usando un csplit que data de 2008. Usando csplit con fecha de 2011 funciona :)
dr0i
4

Tanto heady tailtiene opciones para producir líneas de la "otra" final del archivo de lo que lo haría. Entonces tienes estas dos opciones:

head -n 100 source.txt > file1.txt
head -n -100 source.txt > file2.txt

o (donde NNN es 100 menos que la salida de wc -l source.txt):

tail -n +NNN source.txt > file1.txt
tail -n NNN source.txt > file.txt

Puede leer las páginas del manual para sus versiones heady tailpara obtener más información.

Twalberg
fuente
0

Puede usar 'wc', 'dc', 'head' y 'tail'. Es decir

unix> wc -l foo
545 /tmp/foo
unix> dc -e '545 100 - p'
445
unix> head -n 100 foo > filea
unix> tail -n 445 foo > fileb

Para facilitar su uso, puede convertirlo en un script de shell.


fuente