如何通过 grep 值聚合 find 命令中的匹配项?

如何通过 grep 值聚合 find 命令中的匹配项?

我正在寻找<source_model>.*</source_model>位于以下位置的任何文件的所有出现./vendor/magento/*/etc/adminhtml/system.xml

find ./vendor/magento/ -type f -path */etc/adminhtml/system.xml -exec grep -P "<source_model>.*</source_model>" {} +

但输出的形式是:

./vendor/magento/module-authorizenet-cardinal/etc/adminhtml/system.xml:                        <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>

我想提取值:

<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<source_model>Magento\Captcha\Model\Config\Mode</source_model>
...

这样我就可以排序了。我怎样才能做到这一点?

答案1

当给定多个要搜索的文件时,默认行为grep是将文件名附加到输出的每一行。因此,您看到此输出是因为您使用的是-exec ... +尝试通过将文件集中在一起来启动尽可能少的实例,而不是-exec ... \;单独为每个文件运行命令。因此,您有几个选项(请注意值周围的引号-path,这很重要,否则*shell 在看到它之前将对其进行扩展find):

  1. 使用-exec \;

     find ./vendor/magento/ -type f -path '*/etc/adminhtml/system.xml' \
        -exec grep -P "<source_model>.*</source_model>" {} \;
    
  2. 如果您使用 GNU (grepLinux 系统上的默认设置),您可以使用该-h标志告诉它禁止打印文件名

     find ./vendor/magento/ -type f -path '*/etc/adminhtml/system.xml' \
        -exec grep -hP "<source_model>.*</source_model>" {} +
    

当然,对于所有这些,如果您使用grep支持它的实现,您可能还需要该-o标志,因此grep只会打印该行的匹配部分。

相关内容