Mova 1000 linhas principais do arquivo de texto para um novo arquivo usando comandos do Unix Shell
Pergunta
Desejo copiar as 1000 linhas principais em um arquivo de texto contendo mais de 50 milhões de entradas, para outro novo arquivo e também excluir essas linhas do arquivo original.
Existe alguma maneira de fazer o mesmo com um único comando shell no Unix?
Solução
head -1000 input > output && sed -i '1,+999d' input
Por exemplo:
$ cat input
1
2
3
4
5
6
$ head -3 input > output && sed -i '1,+2d' input
$ cat input
4
5
6
$ cat output
1
2
3
Outras dicas
head -1000 file.txt > first100lines.txt
tail --lines=+1001 file.txt > restoffile.txt
Por curiosidade, encontrei uma caixa com uma versão GNU de sed
(v4.1.5) e testou o desempenho (não acrescentado) de duas abordagens sugeridas até agora, usando um arquivo de texto de 11m de linha:
$ wc -l input
11771722 input
$ time head -1000 input > output; time tail -n +1000 input > input.tmp; time cp input.tmp input; time rm input.tmp
real 0m1.165s
user 0m0.030s
sys 0m1.130s
real 0m1.256s
user 0m0.062s
sys 0m1.162s
real 0m4.433s
user 0m0.033s
sys 0m1.282s
real 0m6.897s
user 0m0.000s
sys 0m0.159s
$ time head -1000 input > output && time sed -i '1,+999d' input
real 0m0.121s
user 0m0.000s
sys 0m0.121s
real 0m26.944s
user 0m0.227s
sys 0m26.624s
Este é o Linux com o qual eu estava trabalhando:
$ uname -a
Linux hostname 2.6.18-128.1.1.el5 #1 SMP Mon Jan 26 13:58:24 EST 2009 x86_64 x86_64 x86_64 GNU/Linux
Para este teste, pelo menos, parece sed
é mais lento que o tail
abordagem (27 seg vs ~ 14 s).
Esta é uma linha de uma vez, mas usa quatro comandos atômicos:
head -1000 file.txt > newfile.txt; tail +1000 file.txt > file.txt.tmp; cp file.txt.tmp file.txt; rm file.txt.tmp
Abordagem Perl:
perl -ne 'if($i<1000) { print; } else { print STDERR;}; $i++;' in 1> in.new 2> out && mv in.new in
Usando tubo:
cat en-tl.100.en | head -10
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow