我有一个包含多个子目录的目录。我想浏览目录和子目录,找到jpg文件并使用mogrify命令转换大小。我想尽可能地动态,这就是我编写脚本的原因。 $1
是我执行bash脚本时传递的第一个参数。运行脚本后,它给我一个关于“ mogrify无法读取[@]%”的错误。我猜我的代码出了点问题,我在bash中还不成熟。谁能告诉我如何动态地执行此脚本,这样会很快。
p.s:jpg文件的名称不是特殊格式...只是一堆数字。
for folder in $1/*
do
for file in "$folder"/*
do
if [ -e "${file[@]%.jpg}" ]; then
mogrify -resize 112x112! "${file[@]%.jpg}"
fi
done
done
答案 0 :(得分:2)
find "$1" -type f -name "*.jpg" -exec mogrify -resize 112x112! {} \;
答案 1 :(得分:2)
如果您愿意使用find
,这将变得非常容易:
#!/usr/bin/env bash
find "$1" \( -iname \*.jpg -o -iname \*.jpeg \) -print0 | while read -r -d $'\0' file; do
# base="${file##*/}" $base is the file name with all the directory stuff stripped off
# dir="${file%/*} $dir is the directory with the file name stripped off
mogify -resize '112x112!' "$file"
done
然后将其放入名为mymog.bash
的文件中
$ chmod 755 mymog.bash
$ mymog.bash /some/dir
注意:
!
对bash
是 special ,因此将其放在单引号中使其变为“ unspecial”,并将其毫无争议地传递给mogrify
命令。 $1
和$file
周围加上双引号。如果您有一个名为/Users/alice/my pictures
的目录并且不使用引号,则mogrify
将获得一个名为/Users/alice/my
的参数和另一个名为pictures
的参数。\(
使用\)
和find
。这使得整个条件(“ match * .jpg”或“ match * .jpeg”)适用于操作-print0
。find
的{{1}}操作,该操作以空终止(零终止)字符串打印每个匹配的文件名。您可以在文件名中间添加换行符。这样可以防止这种情况。-print0
的内置bash
命令默认读取直到换行。我使用read
使其读取每个“行”或“记录”(文件名),直到其末尾为空(零)字符。 (由于-d $'\0'
,每个结尾都为null。)此解决方案(众多解决方案之一)包含两个部分:
-print0
实用程序查找(在给定目录下)以find
或.jpg
结尾的所有文件,而忽略文件名的大小写。 [因此它将匹配.jpeg
甚至.JPG
。]
\.JpEg
这样的绝对路径,它将找到/some/dir
和/some/dir/a.jpg
。/some/dir/sub1/sub2/sub3/b.jpg
的相对路径,它将找到../../nearby/dir
和../../nearby/dir/c.jpg
。../../nearby/dir/sub1/sub2/sub3/d.jpeg
部分以该行的第一个find
结尾。之后,这是一个|
bash
…while
循环。
do
承担file
吐出的每个记录的值。find
所取的每个值,循环(do
和done
之间的所有内容)运行一次。file
开头的两行是注释。它们包含被忽略(跳过)的命令。您可以删除#
以使#
也运行这些命令。我将它们作为示例,以防您需要记录的目录部分或文件名部分。答案 2 :(得分:0)
尝试find
和一个while read
循环:
find "$1" -type f -name '*.jpg' -print | while read fname
do
....
done
如果文件名可能包含换行符等特殊字符,请使用:
find "$1" -type f -name '*.jpg' -print0 | while IFS= read -r -d '' fname
do
....
done
还有更多选项可以调整搜索。