我试图理解为什么我不能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
正如所有评论者已经提到的那样,模式匹配 viased
或 via之间的返回状态之间存在显着差异grep
。
而grep -q
仅返回0
找到的匹配项的状态sed
总是返回,0
无论是否找到匹配项(在某些情况下,文件或流无法读取,并且实际上没有给出0
)。通过sed
GNU 扩展,可以修改此返回状态,即我们可以更改它,以便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 的深刻见解!