sed
以下の例が利用できない理由を理解しようとしています。
すべてのフォルダにというフォルダを含む入れ子になったフォルダ構造がありますPKGBUILD
。たとえば、特定のパターンを含むファイルの相対パスを印刷したいとします。pkgname=.*dbus
find
と一緒に使用すると、grep
期待される結果が得られます。
find . -name 'PKGBUILD' -exec grep -q 'pkgname=.*dbus' {} \; -print
私は正しく得る
./packages/dbus-python/repos/extra-x86_64/PKGBUILD
./packages/dbus-python/trunk/PKGBUILD
./packages/dbus-glib/repos/extra-x86_64/PKGBUILD
./packages/dbus-glib/trunk/PKGBUILD
PKGBUILD
そのファイルには正しいパターンが含まれているため、相対ファイルパスに出力されます。私が理解しているように、-q
grepのオプションは一致するものがない限り印刷を無視します。
ただし、を使用して同じ動作をシミュレートできる必要がありますsed
。私は次のように使用します
find . -name 'PKGBUILD' -exec sed -n '/pkgname.*dbus/q' {} \; -print
whereは出力を省略し、一致するものが見つかったらすぐに終了する-n
ために使用されます。q
ただし、コマンドは以下を出力します。すべて PKGBUILD
一致するかどうかに関係なく、ツリー内のファイルですsed
。grep
ここで動作が異なる理由は何であり、sed
このコマンドを機能させるにはどうすればよいですかsed
?
答え1
すべてのコメント作成者がすでに述べたように、sed
viaパターンの一致またはvia間の戻り状態の間にはかなりの違いがありますgrep
。
一方、見つかった一致grep -q
のみが返される状態は、一致が見つかったかどうかに関係なく常に返されます(場合によってはファイルやストリームを読み取ることができず、実際には提供されません)。 GNU拡張機能を使用すると、この戻り状態を変更できます。つまり、パターン一致が発生した場合にのみ返されるように変更できます。0
sed
0
0
sed
sed
1
sed -n '/pkgname.*dbus/q1'
ただし、このfind
プログラムは前のジョブの戻り状態print
にのみ依存します。つまり、次を使用して戻り状態を無効にする必要があります。0
exec
sed
!
find
thenを使用する完全なコマンドsed
は次のとおりです。
find . -name 'PKGBUILD' ! -exec sed -n '/pkgname.*dbus/q1' {} \; -print
出力を含む
./packages/dbus-python/repos/extra-x86_64/PKGBUILD
./packages/dbus-python/trunk/PKGBUILD
./packages/dbus-glib/repos/extra-x86_64/PKGBUILD
./packages/dbus-glib/trunk/PKGBUILD
予想通り。素晴らしい洞察を提供してくれた@Paul_Pedant、@steeldriver、特に@don_crisstiに感謝します!