Xargs'ın birden çok işlemden çıktıyı kötü bir şekilde birleştirmesini nasıl önleyebilirim?


18

(Alternatif olarak ) xargsseçeneği ile kullanıyorum .--max-args=0-P 0

Bununla birlikte, işlemlerin çıktısı, stdoutdoğru hat ayrımı dikkate alınmaksızın akışa birleştirilir . Bu yüzden sık sık aşağıdaki gibi satırlarla sonuçlanacağım:

<start-of-line-1><line-2><end-of-line-1>

Ben tüm çıkış desen egrepile birlikte kullandığım gibi bu benim sonuç berbat.^xargs

xargsSüreç çıktılarını sırayla yazmaya zorlamanın bir yolu var mı (bir sürecin çıktısı bitişik olduğu sürece herhangi bir düzen)?

Yoksa başka bir çözüm mü?

Düzenleme: kullanım durumu hakkında daha fazla bilgi:

Farklı ana bilgisayarlardan web sayfaları indirmek ve ayrıştırmak istiyorum. Her sayfanın yüklenmesi yaklaşık bir saniye sürdüğü ve birkaç düzine sayfa olduğu için istekleri paralelleştirmek istiyorum.

Komutum aşağıdaki forma sahip:

echo -n $IPs | xargs --max-args=1 -I {} --delimiter ' ' --max-procs=0 \
wget -q -O- http://{}/somepage.html | egrep --count '^string'

Ana bilgisayar IP'leri ($ IPs değişkeni) ve diğer bazı veriler dahil edilen bir bash dosyasından geldiğinden bash ve Perl gibi bir şey kullanmıyorum.


Sorunuza daha eksiksiz bir örnek verebilir misiniz? Şu anda nasıl veya neden kullandığınız açık değildir xargs.
Caleb

Bunun çözümü zor olacaktır, her işlemin stdout'ları için farklı dosya tanımlayıcıları kullanmanız ve satırları toplamak için küçük bir sunucu kullanmanız gerekir. xargsböyle bir özellik sağlamıyor gibi görünüyor.
Stéphane Gimenez

@Caleb İşte, umarım bu yardımcı olur :-)
Christoph Wurm

Kesinlikle hafif bir çözüm değil, ama belki de makeişlerin özelliğini kullanabilirsiniz , bence makeçıktı hatlarını düzgün bir şekilde birleştiriyor.
Stéphane Gimenez

yardım etmek için --line-bufferedbayrak ekliyoregrep
iruvar

Yanıtlar:


6

Bu hile yapmalı:

echo -n $IPs | xargs --max-args=1 -I {} --delimiter ' ' --max-procs=0 \
  sh -c "wget -q -O- 'http://{}/somepage.html' | egrep --count '^string'" | \
  { NUM=0; while read i; do NUM=$(($NUM + $i)); done; echo $NUM; }

Buradaki fikir ayrı sayımlar yapmak ve sonunda bunları toplamaktır. Ayrı sayılar karıştırılacak kadar büyükse başarısız olabilir, ancak durum böyle olmamalıdır.


14

GNU Parallel, bu sorunu çözmek için özel olarak tasarlanmıştır:

echo -n $IPs | parallel -d ' ' -j0 wget -q -O- http://{}/somepage.html | egrep --count '^string'

IP'leriniz bir dosyadaysa daha da güzeldir:

cat IPs | parallel -j0 wget -q -O- http://{}/somepage.html | egrep --count '^string'

Daha fazla bilgi edinmek için giriş videosunu izleyin: http://www.youtube.com/watch?v=OpaiGYxkSuQ


2
Güzel bir araç! Ayrıca, birinin size kedinin çok yakında işe yaramayacağını söyleyeceğine bahse girerim.
Stéphane Gimenez

1
Biliyorum. Ancak okumayı daha kolay buluyorum ve genellikle 48 çekirdekli makinede çalışıyorum, bu nedenle boş çekirdeklerden biri için birkaç ekstra saat çevrimi henüz bir sorun değil.
Ole Tange

Debian depolarında olsaydı paralel iş için mükemmel olurdu.
Christoph Wurm

1
@Legate Debian, burada yeterli olan moreutilsparallel komutunu içerir :parallel -j99 -i sh -c 'wget -q -O- http://{}/somepage.html | egrep -c "^string"' -- $IPs
Gilles 'SO- kötü olmayı bırak'

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.