2012-09-16 18 views
5

Grep veya grep benzeri araçlarla ilgili yardım arıyorum. Bu, grep, egrep, awk, sed veya eşleşmeleri aramak için kullanılan diğer herhangi bir aracı içerir, ancak bunlarla sınırlı değildir. Ama sadece sorunun geri kalanı için grep diyeceğim.Sadece hat numarası için hızlı grep/grep?

Bir dosya için bir dosyayı grep yapmanın hızlı yolunu arıyorum ve aynı zamanda bir eşleşme için bir dosyayı grep yapmanın en hızlı yolunu arıyorum ve eşleştirilen satırın geri kalanını değil sadece satır numarasını döndürün hat. Sözdizimi karmaşık olduğu sürece karmaşıksa, bir program karmaşıklığı içinde kullanacağım sorun değil.

Ayrıca, bir desen için düzenli ifadeye ihtiyacım varsa çalışmam için de bu yönteme ihtiyacım var. Bu nedenle eğer commmand varsayılan olarak destekliyorsa veya 10'dan küçük tüm sayıları aramam gerekiyorsa ya da bazı düzenli ifadeler olması gerekiyorsa, sadece bulabildiğim en hızlı yöntemi arıyorum.

Teşekkürler.

grep -n -m 1 str file | awk -F: '{print $1}' 

Sen argüman değerini değiştirebilirsiniz:

Düzenleme i ile çalışıyorum dosyalar çok büyük olacaktır

, benim test dosyası

cevap

5

KingsIndian'ın grep için -m seçeneği ile hedef olduğunu düşünüyorum, ancak hızınız ana hedefinizse, bu özel kullanım için , awk'dan daha hızlı olabilir. deneyin: -f1 bağımsız değişken yalnızca çıkışına ilk alanı söyler iken -d: argüman, bir saha ayırıcı tabaka olarak iki nokta üst üste kullanmak kesilmiş anlatıyor

grep -n -m 1 regex file | cut -d: -f1 

.

+0

Bu diğer benzerleri gibi çalıştı ama ortalama birkaç yüz milisaniye biraz daha hızlı çalıştı. Sanırım bir kaçını atlamak için ihtiyacım varsa grep -n -m 10 regex dosyasını yaparım. kuyruk -5 | cut -d: -f1 – WojonsTech

+0

Kesimi kullanırken, ayırıcı olarak bir sekmeyi nasıl belirlersiniz? – Bulrush

+0

, sekmeleri sekme olarak ayırıcı olarak kullanır, bu nedenle -d'yi kaldırmanız yeterlidir: – nullrevolution

3

ilk eşleşmeden sonra durdurmak için 1.9GB olduğunu m'un, birçok eşleşmeden sonra duracak farklı bir değere ayarlanması. awk bölümü sadece satır numarasını kapatmak içindir.

5 maç sonra durdurmak için:

grep -n -m 5 str file | awk -F: '{print $1}' 

Düzenleme:
Bunun için tail kullanabilirsiniz. Örneğin, ilk 5 maç atlayıp sonraki 7 yazdırmak için: Bu hızlı ise grep -n -m 12 str file| tail -7 | awk -F: '{print $1}'

+0

oldukça serin biliyor musunuz) en yavaş olduğu fazla 5 kat daha hızlı bu operasyon üzerinde İlk birkaç sonucu atlamak için bir yol varsa ve sonraki 5'i yazdırıp çıkın. Bu projede ihtiyaç duyacağım bir şey ama aynı zamanda sadece şu an için herşeyi çıkarmaya çalışıyorum. – WojonsTech

+1

@WojonsTech bunun için düzenlenmiştir. –

+0

Bu gerçekten harika bir ben asla böyle düşünmemiştim. Ne yapmamızı istediğimize göre awk'den daha hızlı bir şey olup olmadığını biliyor muydunuz, yoksa grep'i geri döndürmenin daha hızlı olması, sonuç kümesine rağmen awk to loop'u zorlamaktan daha iyidir. – WojonsTech

1

emin değilim, ama bu iş gibi görünüyor:

nl -b a "<filename>" | grep "<phrase>" | awk '{ print $1 }' 
+0

bu işe yarar, ancak nl'yi kullanmak yerine, çıktıları satır numaralarıyla almak için grep -n'yi kullanabilirsiniz. – WojonsTech

1

Sen GNU awk kullanarak eşleştirme desen yapabilir ve basitçe hat numaralarını yazdırmak:

awk '/regex/ { print NR }' file.txt 

varsayarsak değerleri boşlukla, çizgiler 10'dan az sayı içeren eğer satır numaralarını bulabilirsiniz:

awk '{ for (i=1; i<=NF; i++) if ($i <= 10) print NR }' file.txt 

Bununla birlikte, bu, 10'dan küçük bir sayıdaki her yinelemenin satır numarasını yazdıracaktır. Bunun istenmeyen olduğunu düşünebilirsiniz. Eğer sort -n için, boru çıkışını sıralanmış gerektiriyorsa

awk '{ for (i=1; i<=NF; i++) if ($i <= 10) array[NR]++ } END { for (i in array) print i }' file.txt 

: Bu nedenle her maç için birden yinelenen satır numaralarını kaldırmak için, bir dizi kullanabilirsiniz. Daha şık bir çözümü tercih ederseniz (örn.) Hiçbir boru ile:

awk '{ for (i=1; i<=NF; i++) if ($i <= 10) array[NR]++ } END { for (j in array) sorted[k++]=j+0; n = asort(sorted); for (j=1; j<=n; j++) print sorted[j] }' file.txt 

DÜZENLEME: Son üç awk komutların herhangi birinde

yukarıda basitçe sonuçları 11 ila 20 dahil göstermek için if ($i <= 10)if ($i >= 11 && $i <= 20) için değiştirin.

+0

tam olarak aradığım değildi ama awk kullanarak çözmek için programlı bir yol gibi görünüyor – WojonsTech

+0

@WojonsTech: Lütfen sormak istediğiniz şeyi _exactly_ ile güncelleyin. Anladığım kadarıyla, bazı normal ifadeleri aramak ve satır numarasını ve eşleşen satırı yazdırmak istiyorsunuz. Belki de ikincisi hakkında net değildim. Bu örnekte: 'awk'/regex/{print NR, $ 0} 'file.txt'. HTH. – Steve

+0

Ayrıca, onu kullanmanın en az sistem hevesli yolunu arıyordum. İnsanların grep kullandığı ve kestiği yerlerde bir şeyler gördüm ve her şeyden çok hızlı çalışıyor, ne kadar garip bir şekilde yığılıyor, ama çalıştığını gördüm, ama sonuçları sınırlamak için en iyi yol arıyor mu? – WojonsTech

1

ben sadece bir nonforking sed çağrıyla bazı testler yaptı ve şanslı değildi, ama benim $ MODEL son satırın parçası olan bir 1 Gigabyte textfile, burada numaralar referans için:

(spoiler: grep, awk -m olduğu

 
[email protected]:~$ ls -lh /dev/shm/test 
-rw-r--r-- 1 user user 979M Jul 8 09:50 /dev/shm/test 
 
[email protected]:~$ sed --version | head -n1 
GNU sed-Version 4.2.1 
[email protected]:~$ time sed -n "/$PATTERN/{=;q}" /dev/shm/test 
206558 

real 0m6.835s 
user 0m6.160s 
sys 0m0.648s 
 
[email protected]:~$ grep -V | head -n1 
grep (GNU grep) 2.14 
[email protected]:~$ time grep -n -m 1 "$PATTERN" /dev/shm/test | cut -d: -f1 
206558 

real 0m1.337s 
user 0m0.592s 
sys 0m0.736s 
 
[email protected]:~$ awk --version | head -n1 
GNU Awk 4.0.1 
[email protected]:~$ time awk "/$PATTERN/ { print NR }" /dev/shm/test 
206558 

real 0m7.176s 
user 0m6.356s 
sys 0m0.776s