Divida um arquivo em dois arquivos em uma determinada linha

12

Estou procurando uma maneira no unix de dividir um arquivo em dois arquivos em um determinado número de linha.

split -l 100 file_nameestá perto do que estou procurando, mas esse comando cria vários arquivos, cada um com 100 linhas. Estou procurando um comando para dividir um arquivo em dois arquivos em um determinado número de linha. Existe uma maneira de fazer isso no unix?

tartaruga
fonte

Respostas:

12

Uma solução um pouco mais rígida:

(head -100 > f1.txt; cat > f2.txt) < input.txt
Rubens
fonte
1
Ótima solução. Sem contar wcantes e o arquivo de entrada ainda é processado apenas uma vez, como na awksolução.
Dubu
2
Há uma pequena chance de headler mais do que apenas 100 linhas para encontrar as primeiras 100 linhas para saída f1.txt; esses bytes extras não serão vistos por cat.
chepner
Isto é tão maldito lento
sdaffa23fdsf
12

Use awk, para que você precise fazer apenas uma passagem pelo arquivo de entrada. O seguinte pressupõe que você deseja as primeiras 122 linhas no primeiro arquivo e o restante no segundo.

awk 'NR < 123 { print >> "top_file"; next } {print >> "bottom_file" }' file_name
chepner
fonte
Isso merece um polegar para cima. se você deseja dividir um arquivo de X para Y, é o mais fácil.
Glenn Plas
Esta é a solução mais fácil de entender. Funcionou como um encanto ... e me faz pensar que devo remover a poeira do meu livro O'Reilly Sed & Awk que eu tenho desde 1999, mais ou menos, a seção sed é bem lida, a seção awk não é muito.
Michael
Isso é melhor do que a solução exceto pelo motivo @chepner mencionado nos comentários. Você perderá caracteres no arquivo 'f2.txt'. Esta solução é precisa e eficiente. awk ftw.
Goran
7

Você pode usar heade tailobter as duas partes:

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

onde Ké o número da linha e Lé o número de linhas da parte inferior (número total de linhas - K).

(você pode obter o número total de linhas usando wc -l file_name).

jh314
fonte
5

Você pode usar csplit(se disponível) para fazer isso:

csplit file N+1

dividirá o arquivo em duas partes, uma parte até (e incluindo) o número da linha Ne a outra parte do número da linha N+1até a última linha.
Se você deseja dividir até (mas não incluindo) o número da linha N:

csplit file N
don_crissti
fonte
Isso é ótimo! Obrigado, resolveu o problema perfeitamente para mim.
Zertrin 01/05/19
Melhor desempenho para dividir arquivos de 20 GB em pedaços.
dr0i
@ dr0i - não é de admirar, csplité otimizado para este trabalho.
31416 don_crissti
Dividindo um arquivo de 200 milhões de linhas de eu fui "memória esgotada" usando uma volta datado csplit a 2008. Usando csplit datado de 2011, funciona :)
dr0i
4

Ambos heade tailtêm opções para produzir linhas a partir do "outro" final do arquivo, caso contrário. Então você tem essas duas opções:

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

ou (onde NNN é 100 menor que a saída de wc -l source.txt):

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

Você pode ler as páginas de manual para suas versões heade tailpara mais informações.

Twalberg
fonte
0

Você pode usar 'wc', 'dc', 'head' e 'tail'. Ou seja,

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 o uso, você pode transformar acima em um script de shell.


fonte