z perl
oszczędza linie wejściowe w zmiennej mieszania z liczbą linii, jak klucz
$ seq 12 20 | perl -nle '
@l = (5,2,3,1);
$a{$.} = $_ if(grep { $_ == $. } @l);
END { print $a{$_} foreach @l } '
16
13
14
12
$.
ma numer linii i grep { $_ == $. } @l
sprawdza, czy liczba linii jest obecny w tablicy @l
który zawiera żądane linii w celu wymagane
jako jedna liniowej @l
zgłoszenia wewnątrz BEGIN
uniknąć inicjalizacja każdej iteracji, a także zapewnienie żadnych pustych linii, czy numer linii jest poza zakresem:
$ seq 50000 > inputFile.txt
$ perl -nle 'BEGIN{@l=(200,33,40000)} $a{$.}=$_ if(grep {$_ == $.} @l); END { $a{$_} and print $a{$_} foreach (@l) }' inputFile.txt > outputFile.txt
$ cat outputFile.txt
200
33
40000
wystarczająco małego wejścia, można zapisać wiersze w tablicy i indeksy drukowania wymagane.Uwaga korektę wykonaną jako wskaźnik zaczyna 0
$ seq 50000 | perl -e '$l[0]=0; push @l,<>; print @l[200,33,40000]'
200
33
40000
rozwiązanie z head
i tail
combo:
$ for i in 200 33 40000; do head -"${i}" inputFile.txt | tail -1 ; done
200
33
40000
porównanie wydajności dla pliku wejściowego seq 50000 > inputFile.txt
$ time perl -nle 'BEGIN{@l=(200,33,40000)} $a{$.}=$_ if(grep {$_ == $.} @l); END { $a{$_} and print $a{$_} foreach (@l) }' inputFile.txt > outputFile.txt
real 0m0.044s
user 0m0.036s
sys 0m0.000s
$ time awk -v line_order="200 33 40000" '
BEGIN {
n = split(line_order, inorder)
for (i=1; i<=n; i++) linenums[inorder[i]]
}
NR in linenums {cache[NR]=$0}
END {for (i=1; i<=n; i++) print cache[inorder[i]]}
' inputFile.txt > outputFile.txt
real 0m0.019s
user 0m0.016s
sys 0m0.000s
$ time for i in 200 33 40000; do sed -n "${i}{p;q}" inputFile.txt ; done > outputFile.txt
real 0m0.011s
user 0m0.004s
sys 0m0.000s
$ time sed -n '33h; 200{p; g; p}; 40000p' inputFile.txt > outputFile.txt
real 0m0.009s
user 0m0.008s
sys 0m0.000s
$ time for i in 200 33 40000; do head -"${i}" inputFile.txt | tail -1 ; done > outputFile.txt
real 0m0.007s
user 0m0.000s
sys 0m0.000s
Jeśli zamierzasz parsować plik kilka razy, to przynajmniej zakończ po wydrukowaniu żądanej linii: 'sed -n" $ {i} {p; q} "' –