【问题标题】:Looping through all files in a given directory [duplicate]循环遍历给定目录中的所有文件[重复]
【发布时间】:2011-07-05 12:27:15
【问题描述】:

这是我想要做的:

为 shell 脚本提供一个参数,该脚本将对所有 jpg、bmp、tif 扩展名的文件运行任务。

例如:./doProcess /media/repo/user1/dir5

并且该目录中的所有 jpg、bmp、tif 文件都将运行特定的任务。

我现在拥有的是:

for f in *
do
  imagejob "$f"  "output/${f%.output}" ;
done

我需要 for 循环的帮助来限制文件类型,并且还有一些方法可以在指定目录而不是当前目录下启动。

【问题讨论】:

    标签: shell


    【解决方案1】:

    使用 shell 扩展而不是 ls

    for file in *.{jpg,bmp,tif}
    do
      imagejob "$file" "output/${file%.output}"
    done
    

    如果你有 bash 4.0+,你可以使用globstar

    shopt -s globstar
    shopt -s nullglob
    shopt -s nocaseglob
    for file in **/*.{jpg,bmp,tif}
    do
      # do something with $file
    done
    

    【讨论】:

    • +1 您缺少结束语。
    • 如何指定运行这个脚本的目录?
    • 我得到一个错误 cannot stat `*.{jpg,bmp,tif}': No such file or directory
    • 此解决方案不适用于包含大量文件的目录;它失败并出现错误“参数列表太长”。
    • 我可能搞错了,抱歉。
    【解决方案2】:
    for i in `ls $1/*.jpg $1/*.bmp $1/*.tif`; do
        imagejob "$i";
    done
    

    这是假设您使用的是类似 bash 的 shell,其中 $1 是给它的第一个参数。

    你也可以这样做:

    find "$1" -iname "*.jpg" -or -iname "*.bmp" -or -iname "*.tif" \
              -exec imagejob \{\} \;
    

    【讨论】:

    • 使用 ls 列出带有 for 循环的文件是不好的做法
    • 查找解决方案很好,但会递归查找名称。 shell globbing 方法可能会因文件名中的空格而中断。
    • 花括号不需要转义。
    【解决方案3】:

    您可以使用带有反引号和 ls 的构造(当然也可以使用任何其他突击队):

    for f in `ls *.jpg *.bmp *.tif`; do ...; done
    

    【讨论】:

    • 使用 ls 列出带有 for 循环的文件是不好的做法
    • 究竟是什么原因?我知道这是空间和非常大的目录的问题,但对于其他情况似乎就足够了。我认为在这种情况下您的解决方案更好,但是如果我想通过另一个命令使用 ls/pipe 其输出的排序选项怎么办?
    • 这是为了防止将来在文件名中出现空格。 (另外,人们称之为,ls 的无用使用)。当您可以从一开始就阻止它时,为什么还要等待您的代码中断。如果您需要使用与ls 结合的其他选项,请使用 while 读取循环(或者您可以设置 IFS )
    • 请参阅“确切原因”,请参阅mywiki.wooledge.org/ParsingLs
    【解决方案4】:

    这里的其他解决方案要么仅限 Bash,要么建议使用 ls,尽管它是 a common and well-documented antipattern。这是在没有ls 的情况下在 POSIX sh 中解决此问题的方法:

    for file in *.jpg *.bmp *.tif; do
        ... stuff with "$file"
    done
    

    如果你有大量的文件,也许你也想看看

    find . -maxdepth -type f \( \
        -name '*.jpg' -o -name '*.bmp' -o -name '*.tif' \) \
        -exec stuff with {} +
    

    这避免了按字母顺序对文件名进行排序的开销。 -maxdepth 1 表示不递归到子目录;显然,如果您确实想递归到子目录,请将其取出或修改。

    find-exec ... + 谓词是一个比较新的介绍;如果您的find 太旧,您可能需要使用-exec ... \; 或将-exec stuff with {} + 替换为

    find ... -print0 |
    xargs -r0 stuff with
    

    然而-print0 选项和xargs 对应的-0 选项又是一个GNU 扩展。

    【讨论】:

      猜你喜欢
      • 2014-06-17
      • 2012-01-20
      • 2017-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多