Disons que j'ai un énorme fichier texte (> 2 Go) et que je veux juste cat
les lignes X
à Y
(par exemple 57890000 à 57890010).
D'après ce que j'ai compris, je peux le faire en reliant head
dans tail
ou vice versa, c'est-à-dire
head -A /path/to/file | tail -B
ou alternativement
tail -C /path/to/file | head -D
où A
,B
,C
et D
peut être calculé à partir du nombre de lignes dans le fichier, X
et Y
.
Mais il y a deux problèmes avec cette approche :
- Vous devez calculer
A
,B
,C
etD
. - Les commandes pourraient
pipe
les uns aux autres beaucoup plus lignes que je ne souhaite pas lire (par exemple, si je ne lis que quelques lignes au milieu d'un fichier volumineux)
Existe-t-il un moyen de faire en sorte que le shell fonctionne simplement avec et affiche les lignes que je veux? (tout en ne fournissant que X
et Y
) ?
Réponse acceptée :
Je suggère le sed
solution, mais par souci d'exhaustivité,
awk 'NR >= 57890000 && NR <= 57890010' /path/to/file
Pour couper après la dernière ligne :
awk 'NR < 57890000 { next } { print } NR == 57890010 { exit }' /path/to/file
Test de vitesse (ici sur macOS, YMMV sur d'autres systèmes) :
- Fichier de 100 000 000 lignes généré par
seq 100000000 > test.in
- Lire les lignes 50 000 000-50 000 010
- Tests sans ordre particulier
real
heure telle que rapportée parbash
time
intégré
4.373 4.418 4.395 tail -n+50000000 test.in | head -n10
5.210 5.179 6.181 sed -n '50000000,50000010p;57890010q' test.in
5.525 5.475 5.488 head -n50000010 test.in | tail -n10
8.497 8.352 8.438 sed -n '50000000,50000010p' test.in
22.826 23.154 23.195 tail -n50000001 test.in | head -n10
25.694 25.908 27.638 ed -s test.in <<<"50000000,50000010p"
31.348 28.140 30.574 awk 'NR<57890000{next}1;NR==57890010{exit}' test.in
51.359 50.919 51.127 awk 'NR >= 57890000 && NR <= 57890010' test.in
Ce ne sont en aucun cas des repères précis, mais la différence est suffisamment claire et reproductible* pour donner une bonne idée de la vitesse relative de chacune de ces commandes.
* :Sauf entre les deux premiers, sed -n p;q
et head|tail
, qui semblent être essentiellement les mêmes.