通过将行传递给外部程序来过滤行的程序?

通过将行传递给外部程序来过滤行的程序?

我正在寻找一个程序来使用外部程序来过滤流的行 - 几乎是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(下面的代码片段在该行周围放置单引号,并用'\''; \047is替换该行中的单引号')。因为每个命令调用都通过 shell,所以我预计这会比纯 shell 方法慢,即使 awk 解析行可能更快。但我还没有做任何基准。

awk '{quoted=$0; gsub(/\047/, "\047\\\\\047\047")}
     !system("predicate \047" $0 "\047")'

相关内容