Söylemenin iyi bir yolu nedir, büyük bir metin dosyasından 20-45 satırları. Etkileşimli olmayan elbette!
Söylemenin iyi bir yolu nedir, büyük bir metin dosyasından 20-45 satırları. Etkileşimli olmayan elbette!
Yanıtlar:
deneyebilirsiniz:
cat textfile | head -n 45 | tail -n 26
veya
cat textfile | awk "20 <= NR && NR <= 45"
Güncelleme:
Mahomedalid'in işaret ettiği gibi, cat
gerekli ve biraz gereksizdir, ancak temiz, okunabilir bir komut sağlar.
Eğer cat
sizi rahatsız yapar daha iyi bir sollution olacaktır:
<textfile awk "20 <= NR && NR <= 45"
,
aralık operatörünü göstermekti.
Daha da basit:
sed -n '20,45p;45q' < textfile
-N bayrağı varsayılan çıkışı devre dışı bırakır. "20,45", 20 ila 45 arasındaki satırları kapsar. "P" komutu geçerli satırı yazdırır. Ve q çizgiyi yazdırdıktan sonra kapanır.
q
Komut kaldırıldığında (her şeyden başlayarak ;
) 27169334 satırlık bir dosyadan tek satır 26995107 ayıklanırken benim için performansı artırdı.
Bu bir cevap değil, yorum olarak gönderemez.
Bunu yapmanın başka bir (çok hızlı) yolu burada mikeserv tarafından önerildi :
{ head -n 19 >/dev/null; head -n 26; } <infile
Burada ve aynı prosedürle aynı test dosyasını kullanarak, bazı karşılaştırmalar (satırları ayıklama 1000020-1000045):
mikeserv :
{ head -n 1000019 >/dev/null; head -n 26; } <iplist
real 0m0.059s
Stefan :
head iplist -n 1000045 | tail -n 26
real 0m0.054s
Bunlar açık ara en hızlı çözümler ve farklar ihmal edilebilir (tek geçiş için) (Farklı aralıklarla denedim: birkaç satır, milyonlarca satır vb.).
Bununla birlikte, borusuz olarak yapılması, benzer şekilde birden fazla çizgi aralığını aramak için gereken bir uygulama için önemli bir avantaj sağlayabilir :
for pass in 0 1 2 3 4 5 6 7 8 9
do printf "pass#$pass:\t"
head -n99 >&3; head -n1
done <<1000LINES 3>/dev/null
$(seq 1000)
1000LINES
... hangi baskı ...
pass#0: 100
pass#1: 200
pass#2: 300
pass#3: 400
pass#4: 500
pass#5: 600
pass#6: 700
pass#7: 800
pass#8: 900
pass#9: 1000
... ve dosyayı yalnızca bir defa okur.
Diğer sed
/ awk
/ perl
çözümleri tüm dosyayı okur ve bu büyük dosyalarla ilgili olduğundan çok verimli değildir. Bazı alternatifler attığım exit
veya q
uit Belirtilen aralıktaki son satırdan sonra:
Stefan :
awk "1000020 <= NR && NR <= 1000045" iplist
real 0m2.448s
vs.
awk "NR >= 1000020;NR==1000045{exit}" iplist
real 0m0.243s
dkagedal ( sed
):
sed -n 1000020,1000045p iplist
real 0m0.947s
vs.
sed '1,1000019d;1000045q' iplist
real 0m0.143s
Steven D :
perl -ne 'print if 1000020..1000045' iplist
real 0m2.041s
vs.
perl -ne 'print if $. >= 1000020; exit if $. >= 1000045;' iplist
real 0m0.369s
awk NR==1000020,NR==1000045 textfile
Sisteminizde bununla ne kadar zaman aldığını görmek güzel olurdu .
ruby -ne 'print if 20 .. 45' file
python -c 'import fileinput, sys; [sys.stdout.write(line) for nr, line in enumerate(fileinput.input()) if 19 <= nr <= 44]'
? :-P Bu, awl / sed'den esinlenerek Perl'den sonra modellenen Ruby'nin kolayca yapabileceği bir şey.
Sed ve awk zaten alınmış olduğundan, işte bir perl çözümü:
perl -nle "print if ($. > 19 && $. < 46)" < textfile
Veya yorumlarda belirtildiği gibi:
perl -ne 'print if 20..45' textfile
perl -ne'print if 20..45' textfile
awk NR==20,NR==45 textfile
da çalışır ve kolayca okur.