두 개의 파이프를 사용할 때 읽기 루프가 첫 번째 줄 이후에 종료되는 것 같습니까?

두 개의 파이프를 사용할 때 읽기 루프가 첫 번째 줄 이후에 종료되는 것 같습니까?
#!/usr/bin/env bash

set -euo pipefail

while read -r line
do
  echo "line via echo:"
  echo "$line"
  echo "line via sed:"
  sed 's/w/f/g' | sed 's/f/zzzzz/g' <<< "$line"
done < /dev/stdin

위의 내용은 한 줄만 출력하는 것 같습니다. 이유는 무엇입니까?

printf "123\n456\n789" | ./srScript.sh
line via echo:
123
line via sed:
123

sed이는 파이프라인의 두 번째 인 것으로 보이며 이를 제거하면 예상대로 작동합니다 sed 's/w/f/g' |. 그런데 왜 이런 일이 발생합니까? 이상해 보입니까?

답변1

파이프 sed라인은 다소 뒤에서 앞으로 이동합니다.

sed 's/w/f/g' | sed 's/f/zzzzz/g' <<< "$line"

이렇게 하면 첫 번째 입력은 표준 입력(즉, your 및 string )에서 읽게 되고 sed두 번째 입력은 ()를 읽게 됩니다. 이 파이프는 첫 번째 파이프의 출력을 차단합니다.456789sed$line123sed어딘가에두 번째는 sed읽지 않기 때문입니다.

나는 당신이 원하는 것 같아요첫 번째 sed두 번째 줄은 sed첫 번째 줄의 출력을 읽습니다.

당신은 이것을 할 것입니다

{ sed 's/w/f/g' | sed 's/f/zzzzz/g'; } <<< "$line"

또는

sed 's/w/f/g' <<<"line" | sed 's/f/zzzzz/g'

또한 이 경우 두 sed호출을 하나로 결합할 수 있습니다.

sed 'y/w/f/; s/f/zzzzz/g' <<<"$line"

또는,

sed -e 'y/w/f/' -e 's/f/zzzzz/g' <<<"$line"

y또한 전체 줄에서 단일 문자를 바꾸는 명령을 사용하도록 첫 번째 표현식을 변경했습니다 .

그러나 그것은희귀한sed별도의 입력 라인을 호출하는 것이 좋습니다. 출력이 필요하지 않은 경우 echo스크립트를 다음과 같이 단순화할 수 있습니다.

#!/bin/sh
sed 'y/w/f/; s/f/zzzzz/g'

심지어

#!/usr/bin/sed -f
y/w/f/
s/f/zzzzz/g

관련 정보