Terminalde çoklu dişli grep nasıl başlatılır?


38

Her biri 2 GB olan 250+ dosyadan oluşan bir klasörüm var. Bu dosyalarda bir string / pattern aramam ve sonucu bir outputdosyada çıkarmam gerekiyor. Aşağıdaki komutu çalıştırabilirim biliyorum ama çok yavaş !!

grep mypattern * > output

Hızlandırmak istiyorum. Java'da programcı olarak, çoklu iş parçacıklığının süreci hızlandırmak için kullanılabileceğini biliyorum. grep"Çok iş parçacıklı modda" nasıl başlayacağım ve çıktıyı tek bir outputdosyaya nasıl yazacağım .




1
Elbette geniş bir dosya koleksiyonunda arama yapmak, IO'ya bağlı bir problemin klasik bir örneğidir. Dolayısıyla birden fazla iş parçacığı kullanmak yardımcı olmaz.
Jonathan Hartley

Yanıtlar:


31

Bunun için iki kolay çözüm var. Temel olarak, xargsveya kullanarak parallel.

xargs Yaklaşımı:

Sen kullanabilirsiniz xargsile findaşağıdaki gibi:

find . -type f -print0  | xargs -0 -P number_of_processes grep mypattern > output

number_of_processesBaşlatılmasını istediğiniz maksimum işlem sayısıyla değiştireceğiniz yer . Ancak, performansınızın G / Ç'nin sınırlı olması durumunda size önemli bir performans göstermesi garanti edilmez. Bu durumda, G / Ç için bekleyen kaybedilen zamanı telafi etmek için daha fazla işlem başlatmayı deneyebilirsiniz.

Ayrıca, bulmanın dahil edilmesiyle, değişiklik zamanı gibi sadece dosya kalıpları yerine daha gelişmiş seçenekler belirleyebilirsiniz.

Stéphane'nin yorumlarında açıklandığı gibi, bu yaklaşımla ilgili olası bir sorun, eğer az dosya varsa, xargsonlar için yeterince fazla işlem başlamayabilir. Çözümlerden biri , bir seferde borudan kaç tane argüman alacağını belirtmek için -nseçeneği kullanmak olacaktır xargs. Ayar -n1, xargsher bir dosya için yeni bir işlem başlatmaya zorlar . Dosyalar çok büyükse (bu sorunun durumunda olduğu gibi) ve göreceli olarak daha az sayıda dosya varsa, bu istenen bir davranış olabilir. Ancak, eğer dosyalar kendileri küçükse, yeni bir işlem başlatmanın yükü, paralellik avantajını zayıflatabilir, bu durumda daha büyük bir -ndeğer daha iyi olacaktır. Bu nedenle, -nseçenek dosya boyutlarına ve sayısına göre ince ayar yapılabilir.

Paralel Yaklaşım:

Bunu yapmanın başka bir yolu, Ole Tange GNU Parallel aracını kullanmaktır parallel( burada bulunabilir ). Bu, paralellik üzerinde daha iyi tanecik kontrolü sağlar ve hatta birden fazla ana bilgisayara dağıtılabilir (örneğin, dizininiz paylaşılıyorsa faydalı olabilir). Paralel kullanan en basit sözdizimi:

find . -type f | parallel -j+1 grep mypattern

Seçeneğin -j+1makinenizdeki çekirdek sayısını aşan bir işlemi başlatmak için paralel talimat verdiği durumlarda (Bu, G / Ç sınırlı işler için faydalı olabilir, hatta sayıca daha yükseğe çıkmayı deneyebilirsiniz).

Paralel ayrıca, xargsher işlemden çıktının sırasını koruma ve bitişik bir çıktı üretme avantajına sahiptir . Örneğin, xargs1. işlem bir satır üretiyorsa p1L1, 2. işlem bir satır oluşturur p2L1, 1. işlem başka bir satır oluşturur p1L2, çıktı şöyle olacaktır:

p1L1
p2L1
p1L2

Oysa parallelçıktı ile:

p1L1
p1L2
p2L1

Bu genellikle xargsçıktıdan daha kullanışlıdır .


1
Muhtemelen -nile birlikte kullanmak istersiniz -P. Aksi takdirde, xargsiki dosya varsa, birkaç işlem ortaya çıkabilir.
Stéphane Chazelas

1
Peki, -n1 grepdosya başına bir tane başlatır . Dosyalar çok büyük olmadıkça ve çok az dosya olmadığı sürece, zaman içinde dosyalarda arama yapmak yerine grep işlemlerini başlatmak ve durdurmak için harcayacağınız zaman muhtemelen biraz arttırmak istersiniz.
Stéphane Chazelas

9

Grep CPU-wise'ı hızlandırmanın en az iki yolu var:

  • Normal bir ifade yerine sabit bir dize arıyorsanız, -Fbayrağı belirtin ;

  • Deseniniz yalnızca ASCII ise, UTF-8 yerine 8 bit yerel ayar kullanın, örn LC_ALL=C grep ....

Bunlar, eğer sabit diskiniz tıkanıklık ise; Bu durumda muhtemelen paralelleştirme de yardımcı olmaz.


1
man grepAz önce "egrep veya fgrep olarak yapılan doğrudan çağrının kullanımdan kaldırıldığı, ancak bunlara dayanan tarihsel uygulamaların değiştirilmemiş olarak çalıştırılmasına izin vermek için sağlanmıştır." Bunun gerçekten önemli olduğundan emin değilim, ancak aynıdırgrep -F
iyrin

1
Ayrıca "bir kalıptan ziyade" derken normal bir ifadeye mi değiniyorsunuz?
iyrin

"Yalnızca ASCII" araması büyük ölçüde daha az CPU kullanıyor. Ancak stackoverflow.com/a/11777835/198219
famzah

3

Sorun G / Ç'ye bağlı değilse, çok çekirdekli işleme için optimize edilmiş bir araç kullanabilirsiniz.

Sift'e bakmak isteyebilirsiniz ( http://sift-tool.org , feragatname: Bu aracın yazarıyım) veya gümüş arayıcı ( https://github.com/ggreer/the_silver_searcher ).

Bir dizge dizgisi araması değil, bir regex deseni kullanıyorsanız, gümüş arayıcısının dosya boyutu 2 GB'dir.


Elbette bir sürü dosyayı araştırmak, IO'ya bağlı bir problemin klasik bir örneğidir?
Jonathan Hartley
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.