Se soubermos o intervalo a selecionar, da primeira linha: lStart
até a última linha: lEnd
, poderíamos calcular:
lCount="$((lEnd-lStart+1))"
Se soubermos a quantidade total de linhas: lAll
, também poderíamos calcular a distância até o final do arquivo:
toEnd="$((lAll-lStart+1))"
Depois, saberemos os dois:
"how far from the start" ($lStart) and
"how far from the end of the file" ($toEnd).
Escolhendo o menor de qualquer um desses: tailnumber
como este:
tailnumber="$toEnd"; (( toEnd > lStart )) && tailnumber="+$linestart"
Nos permite usar o comando de execução consistentemente mais rápido:
tail -n"${tailnumber}" ${thefile} | head -n${lCount}
Observe o sinal de mais ("+") adicional quando $linestart
for selecionado.
A única ressalva é que precisamos da contagem total de linhas, e isso pode levar algum tempo adicional para ser encontrado.
Como é habitual com:
linesall="$(wc -l < "$thefile" )"
Algumas vezes medidas são:
lStart |500| lEnd |500| lCount |11|
real user sys frac
0.002 0.000 0.000 0.00 | command == tail -n"+500" test.in | head -n1
0.002 0.000 0.000 0.00 | command == tail -n+500 test.in | head -n1
3.230 2.520 0.700 99.68 | command == tail -n99999501 test.in | head -n1
0.001 0.000 0.000 0.00 | command == head -n500 test.in | tail -n1
0.001 0.000 0.000 0.00 | command == sed -n -e "500,500p;500q" test.in
0.002 0.000 0.000 0.00 | command == awk 'NR<'500'{next}1;NR=='500'{exit}' test.in
lStart |50000000| lEnd |50000010| lCount |11|
real user sys frac
0.977 0.644 0.328 99.50 | command == tail -n"+50000000" test.in | head -n11
1.069 0.756 0.308 99.58 | command == tail -n+50000000 test.in | head -n11
1.823 1.512 0.308 99.85 | command == tail -n50000001 test.in | head -n11
1.950 2.396 1.284 188.77| command == head -n50000010 test.in | tail -n11
5.477 5.116 0.348 99.76 | command == sed -n -e "50000000,50000010p;50000010q" test.in
10.124 9.669 0.448 99.92| command == awk 'NR<'50000000'{next}1;NR=='50000010'{exit}' test.in
lStart |99999000| lEnd |99999010| lCount |11|
real user sys frac
0.001 0.000 0.000 0.00 | command == tail -n"1001" test.in | head -n11
1.960 1.292 0.660 99.61 | command == tail -n+99999000 test.in | head -n11
0.001 0.000 0.000 0.00 | command == tail -n1001 test.in | head -n11
4.043 4.704 2.704 183.25| command == head -n99999010 test.in | tail -n11
10.346 9.641 0.692 99.88| command == sed -n -e "99999000,99999010p;99999010q" test.in
21.653 20.873 0.744 99.83 | command == awk 'NR<'99999000'{next}1;NR=='99999010'{exit}' test.in
Observe que os horários mudam drasticamente se as linhas selecionadas estiverem próximas do início ou próximas ao final. Um comando que parece funcionar bem em um lado do arquivo, pode ser extremamente lento no outro lado do arquivo.