한 명령의 출력을 여러 명령에 어떻게 전달합니까?


20

공정 대체를 사용하거나 그룹화 및 파이핑을 사용하여 출력 ( stdout )을 다른 명령의 입력으로 출력 할 수 있습니다 .

예 :

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

그러나 반대가 있습니까?

즉, 한 명령의 출력을 다른 많은 명령의 입력으로 한 줄로 보내는 방법이 있습니까?

같은 것 :

cat testfile | wc | tail -n 5

( 문자 그대로 파이프 라인을 취하지 마십시오 ). 여기에 내가의 출력을 전달하는 데 노력하고 cat testfile모두를 wc하고tail -n 5

다른 예는 다음과 같습니다.

( 문의 마지막 단어를 얻기 위해 )

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

답변:


21

빠른 답변. 당신 tee >(what_to_do) >(another_thing_to_do)이 원하는 많은 다른 것들에 대한 명령을 계속 진행 하는 데 사용할 수 있습니다 .

예:

원본 테스트 파일 출력 :

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

tee명령이 추가 된 출력 :

:~$ 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

tee의 각 명령은 add in도 >(head -1 | wc)작동하는 것처럼 명령 행에서 사용할 일반적인 명령 일뿐입니다.

:~$ 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

또는 다음 awk$NF함께 with 를 사용하여 마지막 줄의 마지막 단어를 가져올 수도 있습니다 wc.

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

주 :| 파이프 명령을 끝에 추가하면 명령의 여러 명령을 사용하여 재정의 할 수 있습니다 tee. 테스트하고있는 몇 가지 예가 있습니다.

예 1 (모든 마지막 단어를 당기는 파이프 명령) :

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

예 2 (wc 명령의 출력을 표시하지 않습니다. 3 번째 단어를 잡는 파이프 명령) :

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

예 3 (에코 라인의 세 번째 단어를 가져옵니다. 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

예제 4 (에코 라인의 마지막 단어를 잡아서 가져 오기. 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

이것이 도움이되기를 바랍니다!


3
나는 티와 커피를 좋아한다! '-)
Geek

1
다양한 소비자 간의 출력 순서에 대한 설명 tee은 거짓입니다. 일반적으로 올바른 주문을받는 이유는 저 부하 시스템에서 첫 번째 소비자 프로세스가 먼저 실행되기 때문입니다. 사용량이 많은 컴퓨터에서는 첫 번째 소비자가 인쇄하기 전에 절전 모드로 전환 될 수 있습니다.
Matei David

@MateiDavid 나는 그것을 증명할 수 없으므로 진술을 제거했습니다. 더 큰.
Terrance

2
내 대답을 참조하십시오. 그러나 더 진지하게, tee소비자에 대해 전혀 알지 못합니다 bash. 이 모든 bash수행은 열린 파일 디스크립터를 복사하는 것입니다. 그 외에도 동일한 파일에서 열린 파일 디스크립터에 쓰는 여러 소비자가 있습니다. 커널은이를 처리하지만 bash명령 행 에 나타난 순서 는 영향을 미치지 않습니다.
Matei David

17

tee스트림을 여러 부분으로 분할 해야 합니다. 시험:

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

노트:

  • 여러 프로세스 ( wc, tail)가 모두 stdout에 쓰는 경우 :

    • 출력이 왜곡 될 수 있습니다.

    • 출력이 표시되는 순서는 보장되지 않습니다. 이것을 보려면 sleep 1; wc -w두 번째 소비자로 시도하십시오 .

  • tee목적지가 스트림을 충분히 빨리 소비하지 않으면 차단됩니다. 즉, 대상은 대략 비슷한 속도 (고정 크기 버퍼링 모듈로)로 입력이 공급됩니다. 이 문제를 쉽게 해결할 수있는 방법은 없습니다. 유일한 대안은 스트림을 파일에 저장하고 소비자에게 별도로 공급하는 것입니다. 들어 wctail이 문제가되지 않습니다.

마지막으로 다음과 같이하는 것이 더 간단합니다.

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

5

moreutils패키지는 명령을 제공 pee정확히 않습니다 (당신이 생각하는 무슨 짓을했는지 파이프와 티의 병합을?).

첫 번째 예에서는 다음을 사용합니다.

cat testfile | pee wc "tail -n 5"

두 번째 입력은 마지막 명령에 두 개의 입력을 전달하기 때문에 더 복잡합니다. 나는 아마도 awk다른 대답으로 사용할 것입니다 .

링크 : https://joeyh.name/code/moreutils/

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.