我正在寻找一个程序来使用外部程序来过滤流的行 - 几乎是grep
该程序的一个版本,对于每一行,根据指定的程序是否以零退出代码退出(例如find
' s-exec
选项)。
我知道我可以通过使用循环和子 shell 在 shell 中执行此操作:
some-program |(while read line; do
if predicate "$line"; then
echo "$line"
fi
done)
我想知道是否有一个程序可以让我让这个变得更简单:
some-program |filter predicate
# want negation as well
some-program |filter ! predicate
人们可能会认为增强的 Sed 可能会支持这一点,询问“它是否传递模式空间?”,但 GNU Sed 似乎没有这样的设施。
是否有这样的程序我还没有找到,或者我只需要在shell(或perl)中执行它?
答案1
shell 是非常适合这项工作的工具。请注意不要破坏空格和反斜杠。
while IFS= read -r line; do
if predicate "$line"; then printf '%s\n' "$line"; done
done
您也可以使用 awk。请务必引用每一行,因为它将被传递到 shell(下面的代码片段在该行周围放置单引号,并用'\''
; \047
is替换该行中的单引号'
)。因为每个命令调用都通过 shell,所以我预计这会比纯 shell 方法慢,即使 awk 解析行可能更快。但我还没有做任何基准。
awk '{quoted=$0; gsub(/\047/, "\047\\\\\047\047")}
!system("predicate \047" $0 "\047")'