Bir bölümü metin dosyasından çıkarmanın en iyi yolu nedir?


Yanıtlar:


12

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, catgerekli ve biraz gereksizdir, ancak temiz, okunabilir bir komut sağlar.

Eğer catsizi rahatsız yapar daha iyi bir sollution olacaktır:

<textfile awk "20 <= NR && NR <= 45"

2
awk NR==20,NR==45 textfileda çalışır ve kolayca okur.
ephemient

Stdin kullanımını daha çok seviyorum, nix'in geri kalanıyla küresel bir tutarlılık var
Stefan

1
Komut satırı argümanlarından okumak diğer UNIX yardımcı programlarıyla da tutarlılık gösterir ve asıl amacım awk'ın ,aralık operatörünü göstermekti.
ephemient

lol, @adam demek istedim. ama evet, önerinizi
Stefan

@ Ephemient'in cevabı burada en iyisi. Aksi takdirde, komutlar oldukça şifreli.
Léo Léopold Hertz 준영

13

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.


1
+1 güzel, hoşuma gitti, ancak çizgisi 20 ila 45 :)
Stefan

1
tamam tamam, 20,45 demek için düzenledim :-)
dkagedal

qKomut 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ı.
Ruslan

6

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 exitveya quit 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

+1 Bence buradaki en iyi cevap bu! awk NR==1000020,NR==1000045 textfileSisteminizde bununla ne kadar zaman aldığını görmek güzel olurdu .
Léo Léopold Hertz 준영

3
ruby -ne 'print if 20 .. 45' file

1
bir rubyist, sen benim oy almak efendim
Stefan

1
Biz varken neden olmasın 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.
ephemient

2

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

2
Tüm bu ekstra karakterlerin ne var? Yeni satırları soymaya ve yeniden eklemeye gerek yok, flip-flop satır numarasıyla karşılaştırmayı varsayar ve elmas operatörü sağlandıysa argümanlarla çalışır. perl -ne'print if 20..45' textfile
ephemient

1
Güzel. -nle sanırım bir refleks, geri kalanı için ise, cehaletten kurtulmak için mazeretim yok.
Steven D
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.