Déplacez les 1000 premières lignes d'un fichier texte vers un nouveau fichier à l'aide des commandes de shell Unix
Question
Je souhaite copier les 1 000 premières lignes d'un fichier texte contenant plus de 50 millions d'entrées dans un nouveau fichier et également supprimer ces lignes du fichier d'origine.
Y a-t-il un moyen de faire la même chose avec une seule commande shell sous Unix?
La solution
head -1000 input > output && sed -i '1,+999d' input
Par exemple:
$ 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
Autres conseils
head -1000 file.txt > first100lines.txt
tail --lines=+1001 file.txt > restoffile.txt
Par curiosité, j'ai trouvé une boîte avec une version GNU de sed
(v4.1.5) et testé la performance (non mise en cache) de deux approches suggérées jusqu'à présent, à l'aide d'un fichier texte de 11 millions de lignes:
$ 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
C’est le Linux sur lequel je travaillais:
$ 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
Pour ce test, au moins, il semble que sed
soit plus lent que l'approche tail
(27 s contre ~ 14 s).
Ceci est une ligne mais utilise quatre commandes atomiques:
head -1000 file.txt > newfile.txt; tail +1000 file.txt > file.txt.tmp; cp file.txt.tmp file.txt; rm file.txt.tmp
Approche Perl:
perl -ne 'if($i<1000) { print; } else { print STDERR;}; $i++;' in 1> in.new 2> out && mv in.new in
Utilisation du tuyau:
cat en-tl.100.en | head -10