Làm thế nào để ngăn chặn xargs khỏi đầu ra hợp nhất xấu từ nhiều quy trình?


17

Tôi đang sử dụng xargsvới tùy chọn --max-args=0(cách khác -P 0).

Tuy nhiên, đầu ra của các quy trình được hợp nhất vào stdoutluồng mà không liên quan đến việc tách dòng thích hợp. Vì vậy, tôi thường kết thúc với các dòng như:

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

Khi tôi đang sử dụng egrepvới ^mẫu của tôi trên toàn bộ xargsđầu ra, điều này làm rối tung kết quả của tôi.

Có cách nào để buộc xargsviết các đầu ra của quy trình theo thứ tự (bất kỳ thứ tự nào, miễn là đầu ra của một quy trình tiếp giáp nhau) không?

Hoặc một số giải pháp khác?

Chỉnh sửa: thêm chi tiết về trường hợp sử dụng:

Tôi muốn tải xuống và phân tích các trang web từ các máy chủ khác nhau. Vì mỗi trang mất khoảng một giây để tải và có vài chục trang tôi muốn song song hóa các yêu cầu.

Lệnh của tôi có dạng sau:

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

Tôi sử dụng bash chứ không phải cái gì đó giống như Perl vì IP máy chủ (biến $ IP) và một số dữ liệu khác đến từ tệp bash đi kèm.


Bạn có thể một ví dụ đầy đủ hơn cho câu hỏi của bạn? Không rõ làm thế nào hoặc tại sao bạn hiện đang sử dụng xargs.
Caleb

Giải pháp cho vấn đề này sẽ rất khó khăn, người ta cần sử dụng các bộ mô tả tệp khác nhau cho thiết bị xuất chuẩn của từng quy trình và sử dụng một máy chủ nhỏ để thu thập các dòng. xargsdường như không cung cấp một tính năng như vậy.
Stéphane Gimenez

@Caleb Bạn đi đây, hy vọng điều này sẽ giúp :-)
Christoph Wurm

Chắc chắn không phải là một giải pháp nhẹ, nhưng có lẽ bạn có thể sử dụng maketính năng công việc, tôi nghĩ rằng makehợp nhất các dòng đầu ra đúng cách.
Stéphane Gimenez

không thêm --line-bufferedcờ để egreptrợ giúp
iruvar

Câu trả lời:


6

Cái này cần phải dùng mẹo:

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

Ý tưởng ở đây là tạo ra các số đếm riêng biệt và tổng hợp chúng vào cuối. Có thể thất bại nếu số lượng riêng biệt đủ lớn để trộn lẫn, nhưng nó không phải là trường hợp.


14

GNU Parallel được thiết kế đặc biệt để giải quyết vấn đề này:

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

Nếu IP của bạn nằm trong một tệp, nó thậm chí còn đẹp hơn:

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

Để tìm hiểu thêm hãy xem video giới thiệu: http://www.youtube.com/watch?v=OpaiGYxkSuQ


2
Công cụ tuyệt vời! Ngoài ra, tôi cá rằng ai đó sẽ nói với bạn rằng con mèo vô dụng rất sớm.
Stéphane Gimenez

1
Tôi biết. Nhưng tôi thấy nó dễ đọc hơn và tôi thường làm việc trên các máy 48 lõi, do đó, một vài chu kỳ xung nhịp thêm cho một trong những lõi nhàn rỗi vẫn chưa thành vấn đề.
Ole Tange

song song sẽ là hoàn hảo cho công việc nếu nó nằm trong kho Debian.
Christoph Wurm

1
@Legate Debian bao gồm parallellệnh từ moreutils , điều này là đủ ở đây:parallel -j99 -i sh -c 'wget -q -O- http://{}/somepage.html | egrep -c "^string"' -- $IPs
Gilles 'SO- ngừng trở nên xấu xa'

@Legate checkout build.opensuse.org/package/, đối với tệp .deb và bug.debian.org/cgi-bin/ormsreport.cgi?orms=518696 để sửa lỗi.
Ole Tange
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.