#!/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"
这将导致第一个从标准输入(即您的和字符串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