Làm thế nào tôi có thể chuyển đầu ra của một lệnh cho nhiều lệnh?


20

Sử dụng thay thế quá trình hoặc bằng cách nhóm và đường ống, người ta có thể truyền đầu ra ( stdout ) một tập hợp các lệnh làm đầu vào cho một lệnh khác.

Thí dụ :

wc < <(echo hi;echo bye)
(echo hi; bye) | wc

Nhưng liệu có ngược lại?

Đó là, Có cách nào để gửi đầu ra của một lệnh làm đầu vào cho nhiều lệnh khác trong một dòng không?

Cái gì đó như :

cat testfile | wc | tail -n 5

( Đừng lấy đường ống theo nghĩa đen ). Ở đây tôi đang cố gắng chuyển đầu ra của cat testfilecả hai wctail -n 5

Một ví dụ khác là:

( để có được từ cuối cùng của câu )

echo "some random words"| wc -c | cut -f(out put of wc -c) (output of first echo)

Câu trả lời:


21

Câu trả lời nhanh. Bạn có thể dùngtee >(what_to_do) >(another_thing_to_do) để tiếp tục thực hiện với lệnh của mình cho bao nhiêu điều khác nhau bạn muốn làm.

Thí dụ:

Đầu ra tệp thử nghiệm gốc:

:~$ cat testfile.txt 
Device Model:     LITEONIT LCS-256M6S 2.5 7mm 256GB
Serial Number:    TW0XFJWX550854187616

Đầu ra với teecác lệnh được thêm vào:

:~$ cat testfile.txt | tee >(tail -1) >(wc) >(awk '{print $3,$1,$2}')
Device Model:     LITEONIT LCS-256M6S 2.5 7mm 256GB
Serial Number:    TW0XFJWX550854187616
LITEONIT Device Model:
TW0XFJWX550854187616 Serial Number:
      2      10      91
Serial Number:    TW0XFJWX550854187616

Mỗi lệnh trong tee chỉ là các lệnh thông thường bạn sẽ sử dụng trên dòng lệnh, như add in >(head -1 | wc)work.

:~$ cat testfile.txt | tee >(tail -1) >(head -1 | wc)  >(awk '{print $3,$1,$2}')
Device Model:     LITEONIT LCS-256M6S 2.5 7mm 256GB
Serial Number:    TW0XFJWX550854187616
      1       7      52
LITEONIT Device Model:
TW0XFJWX550854187616 Serial Number:
Serial Number:    TW0XFJWX550854187616

Hoặc bạn cũng có thể lấy từ cuối cùng để nói dòng cuối cùng bằng cách sử dụng awkcùng $NFvới wcnhư thế này:

:~$ cat testfile.txt | tail -1 | tee >(wc) >(awk '{print $NF}')
Serial Number:    TW0XFJWX550854187616
TW0XFJWX550854187616
      1       3      39

LƯU Ý: Thêm |lệnh ống vào cuối có thể ghi đè bằng nhiều lệnh từtee lệnh. Tôi có một số ví dụ ở đây mà tôi đã thử nghiệm:

Ví dụ 1 (Lệnh ống kéo tất cả các từ cuối cùng):

:~$ echo "This is just five words" | tee >(wc -l) >(wc -w) >(wc -c) | awk '{print $NF}'
words
24
5
1

Ví dụ 2 (Không hiển thị đầu ra của các lệnh wc. Lệnh ống lấy từ thứ 3.):

:~$ echo "This is just five words" | tee >(wc -l) >(wc -w) >(wc -c) | awk '{print $3}'
just

Ví dụ 3 (Lấy từ thứ 3 của dòng echo. Lệnh Tee.):

:~$ echo "This is just five words" | tee >(wc -l) >(wc -w) >(wc -c) >(awk '{print $3}')
This is just five words
just
24
5
1

Ví dụ 4 (Lấy từ cuối cùng của dòng echo. Lệnh Tee.):

:~$ echo "This is just five words" | tee >(wc -l) >(wc -w) >(wc -c) >(awk '{print $NF}')
This is just five words
words
24
5
1

Hi vọng điêu nay co ich!


3
Tôi yêu tee và cà phê! '-)
Anh Cả Geek

1
Tuyên bố về thứ tự đầu ra giữa những người tiêu dùng khác nhau teelà sai. Lý do bạn thường nhận được thứ tự chính xác là trên một máy tải thấp, quy trình tiêu dùng đầu tiên được chạy trước. Trên một máy bận hơn, người tiêu dùng đầu tiên có thể được ngủ trước khi in bất cứ thứ gì.
Matei David

@MateiDavid Tôi không thể chứng minh điều đó bằng cách khác, vì vậy tôi chỉ xóa câu lệnh. Không có vấn đề gì
Terrance

2
Xem câu trả lời của tôi. Nhưng nghiêm trọng hơn, teekhông có ý tưởng về người tiêu dùng - họ được tạo ra bởi bashnhững người xử lý dòng. Tất cả những gì bashlàm là sao chép các mô tả tập tin mở. Ngoài ra, bạn có một số người tiêu dùng viết vào phần mô tả tệp được mở trên cùng một tệp. Hạt nhân đảm nhận việc đó, nhưng chắc chắn thứ tự chúng xuất hiện trên bashdòng lệnh sẽ không phải là một yếu tố.
Matei David

17

Bạn cần teechia luồng thành nhiều phần. Thử:

cat testfile | tee >(wc -l) >(wc -w) >(wc -c) | tail -n 5

Ghi chú:

  • Nếu nhiều tiến trình ( wc, tail) đều ghi vào thiết bị xuất chuẩn:

    • Bạn có thể bị cắt xén đầu ra.

    • Không có gì đảm bảo về thứ tự mà đầu ra của chúng sẽ xuất hiện. Để thấy điều này, hãy thử sleep 1; wc -wnhư người tiêu dùng thứ hai.

  • teesẽ chặn nếu bất kỳ điểm đến nào của nó không tiêu thụ luồng đủ nhanh. Có nghĩa là, các điểm đến sẽ được cung cấp đầu vào với tốc độ gần tương tự (modulo bộ đệm kích thước cố định). Không có cách khắc phục dễ dàng nào cho việc này, cách thay thế duy nhất là lưu luồng vào tệp và cung cấp riêng cho người tiêu dùng. Cho wctailđây không phải là một vấn đề.

Đối với từ cuối cùng, nó đơn giản hơn để làm:

echo "some random words" | awk '{print $NF}'

5

Các moreutils gói cung cấp các lệnh pee(merge ống và tee, bạn nghĩ gì?) Mà hiện chính xác điều đó.

Ví dụ đầu tiên của bạn, bạn sẽ sử dụng:

cat testfile | pee wc "tail -n 5"

Ví dụ thứ hai phức tạp hơn vì bạn muốn chuyển hai đầu vào cho lệnh cuối cùng. Tôi có thể sẽ sử dụngawk như các câu trả lời khác.

Liên kết: https://joeyh.name/code/moreutils/

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.