tête, queue, puis ligne?

Quelle est la façon la plus simple d'extraire d'un file une ligne donnée par son numéro. Par exemple, je veux la 666e ligne de somefile . Comment feriez-vous cela dans votre terminal, ou dans un script shell?

Je peux voir des solutions comme head -n 666 somefile | tail -n 1 head -n 666 somefile | tail -n 1 , ou même le demi-incorrect cat -n somefile | grep -F 666 cat -n somefile | grep -F 666 , mais il doit y avoir quelque chose de plus agréable, plus rapide et plus robuste. Peut-être en utilisant une command / utilité unix plus obscure?

sed ( s tream ed itor) est le bon outil pour ce type de travail:

sed -n '666p' somefile

Edit: @ tachomi solution sed '666q;d' somefile est meilleur quand il fonctionne sur un énorme file text, car il fait sortir sed après avoir imprimé le model sans lire le rest du file. Sur tous les autres files, la différence n'est pas pertinente.

Vous pouvez utiliser sed

 sed -n '666p' somefile 

Ou

 sed '666!d' somefile 

Ou dans des files volumineux

 sed '666q;d' somefile 

Dans le script bash

 #!/usr/bin/bash line=666 sed "$line"'q;d' somefile 

POSIXly (et peut-être le plus rapide avec un file énorme):

 tail -n +666 | head -n1 

essayer

 awk 'NR == 666 { print ; exit ; } ' 

ou

 awk -vline=$LINE 'NR == line { print ; exit ; } ' awk 'NR == '$LINE' { print ; exit ; } ' 

si vous voulez fournir un numéro de ligne via une variable shell ($ LINE).

e [dx] it: selon la suggestion de terdon.

Une manière Perl:

 perl -ne 'print && exit if $.==666' file 

J'ai testé en créant un file avec les numéros de 1 à 999999. Sur ce file, la solution Perl ci-dessus et awk avec exit sont les plus rapides de ceux mentionnés jusqu'ici:

 $ perl -le 'print for 1..999999' > file $ time perl -ne 'print && exit if $.==666' file 666 real 0m0.004s user 0m0.000s sys 0m0.000s $ time awk 'NR==666 { print ; exit ; } ' file 666 real 0m0.004s user 0m0.000s sys 0m0.000s $ time tail -n +666 file | head -n1 666 real 0m0.021s user 0m0.004s sys 0m0.000s $ time sed -n '666p' file 666 real 0m0.125s user 0m0.112s sys 0m0.012s $ time awk 'NR==666' file 666 real 0m0.161s user 0m0.156s sys 0m0.000s 

Cela dit, votre solution originale de head -n666 file | tail -n1 head -n666 file | tail -n1 est aussi incroyablement rapide, très robuste et complètement portable. Pourquoi pensez-vous que ce n'est pas le cas?