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?

Respostas:


12

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

(head -100 > f1.txt; cat > f2.txt) < input.txt

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

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).


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

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.


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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.