티셔츠와 끈끈이를 이용한 공예 대체품

티셔츠와 끈끈이를 이용한 공예 대체품

다른 두 명령의 출력을 통해 명령을 파이프한 다음 두 프로세스 대체 결과를 병합하려고 합니다. 나를 가깝게 만든 예는 다음과 같습니다.

command | tee >(sed -rn 's/.*foo (bar).*/1/p') >(awk '{print $3}')

그러나 나는 다음과 같은 목표를 달성하고 싶다.

  • 원래 명령의 입력 스트림을 볼 필요가 없습니다.
  • "붙여넣기"를 사용하여 결과를 병합하고 싶습니다.

한 가지 옵션은 두 개의 개별 명령을 실행하여 파일에 저장하는 것이지만 원하는 만큼 우아하지는 않습니다. Bash에서 이 작업을 수행하는 가장 우아한(한 줄, 명확하게 이해되는) 방법은 무엇입니까?

답변1

원래 명령의 출력이 표시되는 이유는 지정된 파일뿐만 아니라 tee출력 때문입니다. stdout이를 중단하려면 이 출력을 명령 끝에 넣거나 >/dev/null추가 를 추가하여 이 출력을 프로세스 교체 중 하나로 리디렉션할 수 있습니다 >. 예를 들면 다음과 같습니다.

command | tee >(sed -rn 's/.*foo (bar).*/1/p') > >(awk '{print $3}')

또는 더 간단하게 다른 파이프를 사용하면 됩니다.

command | tee >(sed -rn 's/.*foo (bar).*/1/p') | awk '{print $3}'

결합된 두 프로세스 대체를 사용한 결과에 관해서는 paste내가 알지 못하는 모호한 쉘 트릭이 있지 않는 한 명명된 파이프를 사용하지 않고 이를 수행할 수 있는 방법이 없습니다. 궁극적으로 이는 두 줄입니다(명확성을 높이기 위해 형식화됨).

mkfifo /tmp/myfifo
command |
  tee >(sed -rn 's/.*foo (bar).*/1/p' >/tmp/myfifo) |
  awk '{print $3}' |
  paste /tmp/myfifo -

이것을 스크립트에 넣는 경우 임시 명명된 파이프를 생성하라는 제안을 사용하는 것도 고려해 볼 수 있습니다.여기.

답변2

당신이해야 할 일은 입니다 sed.

command | 
sed '/\([^ ][^ ]*  *\)\{2\}/{h
         s///;s/^  *//;s/ .*/p
     g};s/.*foo \(bar\).*/\1/p;d'  

하지만 다른 것에 관해서는, 당신은tee 에 대한문서 |pipe:

cmd1 | {     
    {   tee /dev/fd/3 | 
        cmd2 >&2
    } 3>&1 | 
    cmd3
} 2>&1 |paste

하지만 이미 사용하고 있으므로 sed다음과 같이 사용할 수 있습니다.영리한 tee필요한 경우에만 복사/리디렉션하세요.

cmd | { 
    sed -n 'p;s/.*foo \(bar\).*/\1/w /dev/fd/3' |
    awk ...
} 2>&1

답변3

IMHO 더 우아하고 (명확하게 이해됨) "트릭"을 피합니다 tee. @mikeserv
sed. 명령을 사용한 명령 대체의 예 :awk
printf

$ printf "foo %s %s %s\n"  {1..30} 
foo 1 2 3
foo 4 5 6
foo 7 8 9
foo 10 11 12
foo 13 14 15
foo 16 17 18
foo 19 20 21
foo 22 23 24
foo 25 26 27
foo 28 29 30

요구사항(예):
붙여넣기 출력

  1. sed -rn '/3/ s/[^ ]* ([^ ]*).*/\1/'
    "3"이 있는 행만 선택하고 두 번째 필드를 가져옵니다.
    첫 번째 숫자 1, 13, 22 및 28이 있는 행입니다.
  2. awk 'NR>2 {print $3}'
    모든 행의 세 번째 필드 표시

요구 사항 1의 스트림은 배열로 캡처되고 bar,
요구 사항 2의 스트림은 배열로 캡처됩니다 secondstream.
모든 입력이 처리된 후 캡처된 스트림을 END 블록에 붙여넣습니다.

printf "foo %s %s %s\n"  {1..30} |
   awk '/3/  {bar[barcounter++]=$2}
        NF>2 {secondstream[streamnr++]=$3} 
        END  {for (i=0;i<streamnr;i++) print bar[i], secondstream[i];}
       '

결과:

1 2
13 5
22 8
28 11
 14
 17
 20
 23
 26
 29

관련 정보