วิธีการหยุด xargs จากการรวมเอาท์พุทจากกระบวนการหลายอย่างไม่ดี?


17

ฉันกำลังใช้xargsกับตัวเลือก--max-args=0(หรือ-P 0)

อย่างไรก็ตามเอาต์พุตของกระบวนการถูกรวมเข้ากับstdoutสตรีมโดยไม่คำนึงถึงการแยกบรรทัดที่เหมาะสม ดังนั้นฉันมักจะจบลงด้วยบรรทัดเช่น:

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

ในขณะที่ฉันใช้egrepกับ^ในรูปแบบของฉันในxargsผลลัพธ์ทั้งหมดนี้จะทำให้สับสนผลลัพธ์ของฉัน

มีวิธีบังคับxargsให้เขียนผลลัพธ์ของกระบวนการตามลำดับ (คำสั่งใด ๆ ตราบใดที่ผลลัพธ์ของหนึ่งกระบวนการนั้นต่อเนื่องกัน)?

หรือวิธีการแก้ปัญหาอื่น ๆ ?

แก้ไข:รายละเอียดเพิ่มเติมเกี่ยวกับกรณีการใช้งาน:

ฉันต้องการดาวน์โหลดและแยกหน้าเว็บจากโฮสต์ที่แตกต่างกัน เนื่องจากทุกหน้าใช้เวลาประมาณหนึ่งวินาทีในการโหลดและมีหน้าเว็บไม่กี่โหลที่ฉันต้องการขนานการร้องขอ

คำสั่งของฉันมีแบบฟอร์มต่อไปนี้:

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

ฉันใช้ bash และไม่ใช่อย่าง Perl เพราะ host IP (ตัวแปร $ IP) และข้อมูลอื่น ๆ มาจากไฟล์ bash ที่รวมอยู่


คุณสามารถยกตัวอย่างให้กับคำถามของคุณได้มากขึ้นหรือไม่? xargsมันไม่ชัดเจนว่าทำไมคุณกำลังใช้
แม็กเคเล็บ

วิธีแก้ปัญหานี้จะยากเราต้องใช้ตัวอธิบายไฟล์ที่แตกต่างกันสำหรับ stdout ของแต่ละกระบวนการและใช้เซิร์ฟเวอร์ขนาดเล็กเพื่อรวบรวมบรรทัด xargsดูเหมือนจะไม่ได้ให้คุณสมบัติดังกล่าว
Stéphane Gimenez

@Caleb ไปแล้วหวังว่านี่จะช่วย :-)
Christoph Wurm

ไม่ใช่โซลูชันที่มีน้ำหนักเบาแน่นอน แต่บางทีคุณอาจใช้makeคุณลักษณะงานของฉันคิดว่าการmakeรวมสายออกอย่างถูกต้อง
Stéphane Gimenez

จะเพิ่มการ--line-bufferedตั้งค่าสถานะเพื่อegrepช่วย
iruvar

คำตอบ:


6

สิ่งนี้ควรทำเคล็ดลับ:

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; }

ความคิดที่นี่คือการนับแยกและรวมสิ่งเหล่านี้ในตอนท้าย อาจล้มเหลวหากจำนวนแยกต่างหากมีขนาดใหญ่พอที่จะนำมาผสม แต่ไม่ควรเป็นเช่นนั้น


14

GNU Parallel ได้รับการออกแบบมาเป็นพิเศษเพื่อแก้ปัญหานี้:

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

หาก IP ของคุณอยู่ในไฟล์มันจะสวยกว่า:

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

หากต้องการเรียนรู้เพิ่มเติมดูวิดีโอแนะนำ: http://www.youtube.com/watch?v=OpaiGYxkSuQ


2
เครื่องมือที่ดี! นอกจากนี้ฉันเดิมพันว่ามีคนจะบอกคุณว่าแมวนั้นไร้ประโยชน์เร็ว ๆ นี้
Stéphane Gimenez

1
ฉันรู้ว่า. แต่ฉันคิดว่ามันอ่านง่ายขึ้นและฉันมักจะทำงานกับเครื่อง 48 แกนดังนั้นรอบนาฬิกาพิเศษสองสามดวงสำหรับหนึ่งในแกนกลางที่ว่างก็ยังคงเป็นปัญหาอยู่
Ole Tange

แบบขนานจะสมบูรณ์แบบสำหรับงานถ้ามันอยู่ในที่เก็บ Debian
Christoph Wurm

1
@Legate Debian รวมถึงparallelคำสั่งจากmoreutilsซึ่งเพียงพอที่นี่:parallel -j99 -i sh -c 'wget -q -O- http://{}/somepage.html | egrep -c "^string"' -- $IPs
Gilles 'ดังนั้น - หยุดความชั่วร้าย'

@Lateate checkout build.opensuse.org/package/…สำหรับไฟล์. deb และbugs.debian.org/cgi-bin/bugreport.cgi?bug=518696สำหรับข้อผิดพลาดที่จะผลักดัน
Ole Tange
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.