Você deve usar sed
.
sed -n -e 45000000,45000100p -e 45000101q bigfile > savedlines
Isso diz a sed
para imprimir as linhas 45000000-45000100, inclusive, e para sair na linha 45000101.
Eu tenho um problema com a exibição de blocos de um arquivo de texto muito grande. Este arquivo, aproximadamente 19 GB, é obviamente grande demais para ser visualizado por qualquer meio tradicional.
Eu tentei head 1
e tail 1
( head -n 1
e tail -n 1
) com os dois comandos reunidos de várias maneiras (para chegar a uma parte no meio) sem sorte. Minha máquina Linux com o Ubuntu 9.10 não pode processar este arquivo.
Como faço para lidar com esse arquivo? Meu objetivo final é aprimorar as linhas 45000000 e 45000100.
Crie um banco de dados MySQL com uma única tabela que tenha um único campo. Em seguida, importe seu arquivo para o banco de dados. Isso tornará muito fácil procurar uma determinada linha.
Eu não acho que mais nada poderia ser mais rápido (se head
e tail
já falharem). No final, o aplicativo que deseja encontrar a linha n
precisa procurar por todo o arquivo até encontrar n
newlines. Sem algum tipo de pesquisa (índice de linha para byte offset em arquivo), nenhum melhor desempenho pode ser alcançado.
Dado o quão fácil é criar um banco de dados MySQL e importar dados para ele, eu sinto que essa é uma abordagem viável.
Veja como fazer isso:
DROP DATABASE IF EXISTS helperDb;
CREATE DATABASE 'helperDb';
CREATE TABLE 'helperDb'.'helperTable'( 'lineIndex' BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, 'lineContent' MEDIUMTEXT , PRIMARY KEY ('lineIndex') );
LOAD DATA INFILE '/tmp/my_large_file' INTO TABLE helperDb.helperTable (lineContent);
SELECT lineContent FROM helperTable WHERE ( lineIndex > 45000000 AND lineIndex < 45000100 );
/tmp/my_large_file
seria o arquivo que você deseja ler.
A sintaxe correta para importar um arquivo com valores delimitados por tabulações em cada linha é:
LOAD DATA INFILE '/tmp/my_large_file' INTO TABLE helperDb.helperTable FIELDS TERMINATED BY '\n' (lineContent);
Outra grande vantagem disso é que, se você decidir mais tarde extrair outro conjunto de linhas, não precisará esperar horas pelo processamento novamente (a menos que você exclua o banco de dados, é claro).
Duas boas e velhas ferramentas para arquivos grandes são join
e split
. Você pode usar a divisão com a opção --lines=<number>
que cortou o arquivo em vários arquivos de determinado tamanho.
Por exemplo, split --lines=45000000 huge_file.txt
. As partes resultantes seriam em xa, xb, etc. Então você pode head
a parte xb que incluiria as linhas que você queria. Você também pode 'juntar' arquivos de volta para um único arquivo grande.
Você tem as ferramentas certas, mas as usa incorretamente. Como anteriormente respondeu ao U & L, tail -n +X file | head -n Y
(observe o +
) é 10-15% mais rápido que sed
para linhas Y iniciadas em X. E, convenientemente, você não precisa explicitamente exit
do processo como sed
.
tail will read and discard the first X-1 lines (there's no way around that), then read and print the following lines. head will read and print the requested number of lines, then exit. When head exits, tail receives a SIGPIPE signal and dies, so it won't have read more than a buffer size's worth (typically a few kilobytes) of lines from the input file.