私は外部プログラムを使用してストリームラインをフィルタリングするプログラムを探しています。grep
このプログラムのほとんどのバージョンは、各行に対して指定されたプログラムがゼロ終了コード(例:find
の-exec
オプション)で終了したかどうかに基づいています。 )。
ループとサブシェルを使用してシェルでこれを実行できることを知っています。
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にはそのような機能がないようです。
まだ見つからないプログラムはありますか?それともシェル(またはPerl)で実行する必要がありますか?
答え1
シェルはこれを行うための素晴らしいツールです。スペースやバックスラッシュを壊さないように注意してください。
while IFS= read -r line; do
if predicate "$line"; then printf '%s\n' "$line"; done
done
awkを使用することもできます。各行がシェルに渡されるときに引用符を付ける必要があります(下のコードスニペットは行の周りに一重引用符を配置し、行の一重引用符を'\''
; isに置き換えます)。すべてのコマンド呼び出しはシェルを通過するので、awkが行を解析するのにより速くても、これは純粋なシェルアプローチよりも遅いと予想されます。しかし、まだベンチマークをしたことはありません。\047
'
awk '{quoted=$0; gsub(/\047/, "\047\\\\\047\047")}
!system("predicate \047" $0 "\047")'