【问题标题】:Loop through all files in a directory and subdirectories using Bash [duplicate]使用 Bash 遍历目录和子目录中的所有文件 [重复]
【发布时间】:2019-01-10 06:00:17
【问题描述】:

我知道如何遍历目录中的所有文件,例如:

for i in *
do
  <some command>
done

但我想浏览目录中的所有文件,包括(尤其是!)子目录中的所有文件。有没有一种简单的方法可以做到这一点?

【问题讨论】:

    标签: bash


    【解决方案1】:

    find 命令对于这类事情非常有用,前提是文件名中没有空格或其他特殊字符:

    例如:

    for i in $(find . -type f -print)
    do
        stuff
    done
    

    该命令从搜索开始(第一个参数)生成相对路径名。

    正如所指出的,如果您的文件名包含空格或其他字符,这将失败。

    您也可以使用-exec 选项来避免文件名中的空格问题。它为找到的每个文件执行给定的命令。大括号是文件名的占位符:

    find . -type f -exec command {} \;
    

    【讨论】:

    • find 是对的,但是对于包含空格、换行符或 shell 元字符的文件名,像这样迭代其输出会失败。
    【解决方案2】:

    findxargs 是递归处理目录和子目录内容的好工具。例如

    find . -type f -print0 | xargs -0 command
    

    将对当前目录及其子目录中的批量文件运行command-print0-0 参数避免了包含空格、引号或其他元字符的文件名的常见问题。

    如果command 只接受一个参数,您可以使用-L1 限制传递给它的文件数。

    find . -type f -print0 | xargs -0 -L1 command
    

    正如 alexgirao 所建议的,xargs 也可以使用-I 命名参数,如果command 采用选项,这将提供一些灵活性。 -I 暗示 -L1

    find . -type f -print0 | xargs -0 -Iarg command arg --option
    

    【讨论】:

    • 不错的答案,也许您还应该举例说明 -I 标志的使用,这意味着 -L1 并允许参数位置,如本例所示:seq 10 | xargs -Iarg echo arg --more
    • find 还有自己的-exec 选项,效果很好。但它有一些缺点,比如你必须记住用 \; 终止命令,但是 xargs 在安全地并行运行任务以及检测任何命令失败的方式中也很有用。
    • 我对这个答案有点困惑。虽然有帮助,但它似乎涉及一些不必要的步骤/部分。我已经编写了这个 sn-p 代码(使用这个和其他答案),这似乎可以满足我的要求:find . -type f | while read line; do echo $line # Or some other command for each file encountered; done。这样做有什么我遗漏的/潜在的陷阱吗?
    • @Sebastian 是的,确实,使用while read 循环存在问题。最糟糕的是,它不适用于包含空格或引号的文件名。所有-print0 的东西可能看起来没有必要,但多年来我经常被遗漏它所困扰。你会认为我现在已经学会了 :-) 另外,如果你可以在没有-L1 的情况下使用xargs,一切都会运行得更快。
    【解决方案3】:
    recurse() {
      path=$1
      If [ -d "$path" ] ; then
         for i in "$path/"*
         do
            recurse "$i"
         done
      elif [ -f "$path" ] ; then
         do-something
      fi
    }
    

    调用recurse 并将第一个位置参数作为您要开始的目录路径传递。

    例如:recurse /path

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    • 1970-01-01
    • 2013-10-09
    • 2012-01-20
    • 1970-01-01
    • 2015-03-05
    相关资源
    最近更新 更多