循环遍历目录以获取图像文件

use*_*918 1 bash image find mogrify

我有一个包含多个子目录的目录。我想浏览目录和子目录并找到 jpg 文件并使用 mogrify 命令转换大小。我希望尽可能动态地完成它,这就是我编写脚本的原因。这$1是我在执行 bash 脚本时传递的第一个参数。运行脚本后,它给我一个关于“mogrify无法读取[@]%”的错误。我猜我的代码有问题,而且我对 bash 还不成熟。谁能告诉我如何动态地执行这个脚本,这样会很快。

ps:jpg 文件的名称不是特殊格式...只是一堆数字。

for folder in $1/*
do
    for file in "$folder"/*
    do
        if [  -e "${file[@]%.jpg}" ]; then
            mogrify -resize 112x112! "${file[@]%.jpg}"
        fi

    done
done
Run Code Online (Sandbox Code Playgroud)

Col*_*zer 7

如果您愿意使用find,那么这将变得非常简单:

\n\n
#!/usr/bin/env bash\nfind "$1" \\( -iname \\*.jpg -o -iname \\*.jpeg \\) -print0 | while read -r -d $\'\\0\' file; do\n  # base="${file##*/}" $base is the file name with all the directory stuff stripped off\n  # dir="${file%/*}    $dir is the directory with the file name stripped off\n  mogify -resize \'112x112!\' "$file"\ndone\n
Run Code Online (Sandbox Code Playgroud)\n\n

mymog.bash将其放入名为then的文件中

\n\n
$ chmod 755 mymog.bash\n$ mymog.bash /some/dir\n
Run Code Online (Sandbox Code Playgroud)\n\n

笔记:

\n\n
    \n
  • !特殊bash,因此将其放在单引号中使其“不特殊”,将其mogrify不受干扰地传递给命令。
  • \n
  • 如果目录或文件名中包含空格,则需要用$1双引号将 和 括起来。$file如果您有一个名为 的目录/Users/alice/my pictures并且没有使用引号,mogrify则将得到一个名为 的参数/Users/alice/my,另一个名为 的参数pictures
  • \n
  • 确保使用\\(\\)for find。这使得整个条件(“match *.jpg”或“match *.jpeg”)适用于该操作-print0
  • \n
  • 我使用了find\ 的-print0操作,它用空终止(零终止)字符串打印每个匹配的文件名。您可以使用中间包含换行符的文件名。这可以防止这种情况发生。
  • \n
  • bash\ 的内置read命令默认读取到换行符。我使用 使其-d $\'\\0\'读取每个“行”或“记录”(文件名),直到其末尾的空(零)字符。(由于 .,每个都以 null 结尾-print0。)
  • \n
\n\n

该解决方案(众多解决方案之一)有两个部分:

\n\n
    \n
  1. 它使用该find实用程序查找(在给定的目录下)以.jpg或结尾的所有文件.jpeg,忽略文件名的大小写。[因此它将匹配.JPG或什至\\.JpEg。] \n\n
      \n
    • 它为每个文件输出一条记录。
    • \n
    • 如果你给它一个绝对路径,比如/some/dir,它会找到/some/dir/a.jpg/some/dir/sub1/sub2/sub3/b.jpg
    • \n
    • 如果你给它一个相对路径,比如../../nearby/dir,它会找到../../nearby/dir/c.jpg../../nearby/dir/sub1/sub2/sub3/d.jpeg
    • \n
  2. \n
  3. find部分以该行的第一部分结束|。之后就是bash while\xe2\x80\xa6do循环。\n\n
      \n
    • 该变量file采用 吐出的每个记录的值find
    • \n
    • 对于每个采用的值,循环( 和 之间的所有内容do)运行一次。donefile
    • \n
    • 以 开头的两行#是注释。它们包含被忽略(跳过)的命令。您也可以删除#bash运行这些命令。我将它们作为示例包含在内,以防您需要记录的目录部分或仅文件名部分。
    • \n
  4. \n
\n