【问题标题】:Use lines in a file as filenames for grep?使用文件中的行作为 grep 的文件名?
【发布时间】:2009-03-27 10:08:27
【问题描述】:

我有一个包含文件名(以及它们的完整路径)的文件,我想在所有文件中搜索一个单词。 一些伪代码来解释:

grep keyword <all files specified in files.txt>

cat files.txt > grep keyword
cat files txt | grep keyword

问题是我只能通过 grep 来搜索文件名,而不是实际文件的内容。

【问题讨论】:

    标签: shell grep


    【解决方案1】:
    cat files.txt | xargs grep keyword
    

    grep keyword `cat files.txt`
    

    或(相当于以前但更难读错)

    grep keyword $(cat files.txt)
    

    应该可以解决问题。

    陷阱:

    • 如果 files.txt 包含带空格的文件名,则任何一种解决方案都会出错,因为“This is a filename.txt”将被解释为四个文件,“This”、“is”、“a”和“filename.txt”。文本”。永远不要在文件名中包含空格的一个很好的理由。

      • 有很多方法可以解决这个问题,但没有一个是微不足道的。 (find ... -print0 / xargs -0 就是其中之一。)
    • 第二个 (cat) 版本可能会导致很长的命令行(超出环境限制时可能会失败)。第一个(xargs)版本自动处理长输入; xargs 提供了几个选项来控制细节。

    【讨论】:

    • xargs 不会为它从标准输入读取的每一行生成一个单独的进程。 xargs 将使用尽可能多的参数调用 grep(比如 ARG_MAX)。调用 grep 的次数是 ceil(num_files/ARG_MAX)。
    • 正确...我在这方面误读了 xargs 手册页。已编辑。 (xargs 的实际限制可以通过“xargs --show-limits”来确定。
    【解决方案2】:

    DevSolar 的两个答案都有效(在 Linux Ubuntu 上测试),但如果文件很多,xargs 版本更可取,因为它可以避免遇到命令行长度限制。

    所以:

    cat files.txt | xargs grep keyword
    

    要走的路

    【讨论】:

    【解决方案3】:
    tr '\n' '\0' <files.txt | LANG=C xargs -r0 grep -F keyword
    
    • tr 将使用 NUL 字符分隔名称,以便空格不重要(注意 xargs 对应的 -0 选项)。
    • xargs -r 将为“大量”文件启动单个 grep 进程,但如果没有文件则不启动任何 grep 进程。
    • LANG=C 表示使用快速例程进行匹配,而不是使用慢速语言环境的例程
    • grep -F 表示使用快速字符串匹配而不是慢速正则表达式匹配

    【讨论】:

    • 一旦文件名不是 ASCII-7,LANG=C 是否会失败?
    • 不适用于固定字符串编号。如果你不想 grep 像 '[:upper:]' 那么是的。
    【解决方案4】:

    bashksh & zsh 版本:

    grep keyword $(<files.txt)
    

    【讨论】:

      【解决方案5】:

      上次创建 bash shell 脚本的时间很长,但您可以将第一个 grep 的结果(查找所有文件名的那个)存储在一个数组中并对其进行迭代,发出更多的 grep 命令。

      一个好的起点应该是 bash 脚本指南。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-07-30
        • 1970-01-01
        • 2018-08-04
        • 2013-06-04
        • 2016-10-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多