【问题标题】:Search presence of pattern in multiple files在多个文件中搜索模式的存在
【发布时间】:2018-03-15 21:16:24
【问题描述】:

我需要确保我在父目录中找到的所有文件都具有特定的模式。 示例:

./a/b/status: *foo*foo
./b/c/status: bar*bar
./c/d/status: foo

该命令应该返回 false,因为文件 2 没有 foo。 我在下面尝试,但不知道如何在单个命令中实现这一点。

find . -name "status" | xargs grep -c "foo"

【问题讨论】:

    标签: shell unix command-line grep


    【解决方案1】:

    -c 选项计算找到模式的次数。您不需要find,而是使用-r--include grep 选项。

    $ grep -r -c foo --include=status
    

    -r 递归搜索patterh foo 以查找匹配status 的文件。

    示例。我在三个目录中有四个文件。每个都有一行;

    $ cat a/1.txt b/1.txt b/2.txt c/1.txt 
    foobar
    bar
    foo
    bazfoobar
    

    使用上面的grep,你会得到这样的东西,

    $ grep -ir -c foo --include=1.txt
    a/1.txt:1
    b/1.txt:0
    c/1.txt:1
    

    【讨论】:

    • 1.此 grep 是否在整个目录中查找模式,然后仅包含“包含”文件中的搜索?这太慢了,因为 find 减少了我的搜索空间。
    • 是的,-r 选项对--include 中的文件进行递归搜索,然后搜索模式。
    【解决方案2】:

    可以统计不包含“foo”的文件的个数,如果number>0则表示至少有一个文件不包含“foo”:

    find . -type f -name "status" | xargs grep -c "foo" | grep ':0$' | wc -l
    

    find . -type f -name "status" | xargs grep -c "foo" | grep -c ':0$' 
    

    或 使用 iamauser 答案优化(谢谢):

    grep -ir -c "foo" --include=status | grep -c ':0$'
    

    如果树中的所有文件都命名为“status”,您可以使用更简单的命令行:

    grep -ir -c "foo"  | grep -c ':0$'
    

    带检查

    r=`grep -ir -c foo  | grep -c ':0$'`
    if [ "$r" != "0" ]; then
       echo "false"
    fi
    

    【讨论】:

      【解决方案3】:

      如果你想让find输出xargs可以读取的文件列表,那么你需要使用:

      find . -name "status" -print0 | xargs -0 grep foo` to avoid filenames with special characters (like spaces and newlines and tabs) in them.
      

      但我的目标是这样的:

      find . -name "status" -exec grep "foo" {} \+
      

      \+ 终止-exec 导致find 将它找到的所有文件附加到grep 命令的单个实例上。这比为找到的每个文件运行一次 grep 效率要高得多,如果您使用 \; 就会这样做。

      grep 的默认行为将显示文件名和匹配项,正如您在问题中所显示的那样。您可以使用以下选项更改此行为:

      • -h ... 不显示文件名
      • -l ... 只显示匹配的文件,不显示匹配的文本,
      • -L ... 仅显示不匹配的文件 - 即没有模式的文件。

      这最后一个听起来像你真正想要的。

      【讨论】:

        【解决方案4】:
        find . -name 'status' -exec grep -L 'foo' {} + | awk 'NF{exit 1}'
        

        如果所有文件都包含'foo',则上面的退出状态将为0,否则为1。

        【讨论】:

          猜你喜欢
          • 2021-03-13
          • 1970-01-01
          • 1970-01-01
          • 2010-09-14
          • 1970-01-01
          • 2012-09-27
          • 2014-11-23
          • 2021-10-12
          • 1970-01-01
          相关资源
          最近更新 更多