【问题标题】:Find directories where a text is found in a specific file查找在特定文件中找到文本的目录
【发布时间】:2021-12-14 09:38:15
【问题描述】:

如何找到在特定文件中找到文本的目录?例如。我想获取“/var/www/”中包含composer.json 文件中文本“foo-bundle”的所有目录。我有一个已经执行的命令:

find ./ -maxdepth 2 -type f -print | grep -i 'composer.json' | xargs grep -i '"foo-bundle"'

但是我想制作一个sh 脚本来获取所有这些目录并使用它们进行操作。有什么想法吗?

【问题讨论】:

    标签: linux sh


    【解决方案1】:

    您当前的命令几乎就在那里,而不是使用xargsgrep,让我们:

    1. grep 移动到-exec
    2. 使用xargs 将结果传递给dirname 以仅显示父文件夹
    find ./ -maxdepth 2 -type f -exec grep -l "foo-bundle" {} /dev/null \; | xargs dirname
    

    如果您只想搜索composer.json 文件,我们可以像这样包含-iname 选项:

    find ./ -maxdepth 2 -type f -iname '*composer.json' -exec grep -l "foo-bundle" {} /dev/null \; | xargs dirname
    

    如果| xargs dirname 没有提供足够的数据,我们可以扩展它,所以我们can loop over the results of find 使用while read 像这样:

    find ./ -maxdepth 2 -type f -iname '*composer.json' -exec grep -l "foo-bundle" {} /dev/null \; | while read -r line ; do
        parent="$(dirname ${line%%:*})"
        echo "$parent"
    done
    

    我们可以使用to search for all files containing a specific text

    looping over each line之后,我们可以

    1. Remove behind the :获取文件路径
    2. 使用dirname 获取parent folder path

    考虑这个文件设置,/test/b/composer.json 包含 foo-bundle

    ➜  /tmp tree
    .
    ├── test
    │   ├── a
    │   │   └── composer.json
    │   └── b
    │       └── composer.json
    └── test.sh
    

    运行以下test.sh时:

    #!/bin/bash
    
    grep -rw '/tmp/test' --include '*composer.json' -e 'foo-bundle' | while read -r line ; do
        parent="$(dirname ${line%:*})"
        echo "$parent"
    done
    

    结果如预期,文件夹b的路径:

    /tmp/test/b
    

    【讨论】:

    • 这是一个递归 grep,我的目录太大了。我只需要 composer.json 文件上的 grep
    • 哎呀,忘了补充。我们可以使用--include '*composer.json' 让 grep 只搜索作曲家文件。我已经编辑了我的答案!
    • 它仍然是一个递归 grep。时间太长了。我应该只读二级目录
    • 但是,我想我可以将我的 find 命令与您的 while 逻辑结合起来。我试试看
    • 啊,不确定grep 是否有max-depth 类似选项。我建议使用第一种find 方式。
    【解决方案2】:

    感谢@0stone0 带路。我终于明白了:

    #!/bin/sh
    
    find /var/www -maxdepth 2 -type f -print | grep -i 'composer.json' | xargs grep -i 'foo-bundle' | while read -r line ; do
        parent="$(dirname ${line%%:*})"
        echo "$parent"
    done
    

    【讨论】:

    • 请看我的edited answer。我们可以使用find-iname 选项移除1 个管道。可能会提高速度,因为我们不需要使用管道。
    【解决方案3】:

    要查找包含特定文本的所有文件,您可以使用:

    find ./ -maxdepth 2 -type f -exec grep -l "composer.json" {} /dev/null \;
    

    结果是文件名列表。现在您需要做的就是找到一种在所有这些设备上启动命令dirname 的方法。 (我尝试使用简单的管道,但这太容易了:-))

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-07
      • 1970-01-01
      • 1970-01-01
      • 2023-01-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多