#!/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
두 번째 입력은 ()를 읽게 됩니다. 이 파이프는 첫 번째 파이프의 출력을 차단합니다.456
789
sed
$line
123
sed
어딘가에두 번째는 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