如果有人能告诉我在哪里可以学到更多关于这类工作的知识,我将不胜感激。我有一些使用 php 编写脚本的经验,并且一直在学习 Linux(通过 SSH 和 SFTP 使用 Ubuntu 服务器 CLI 将文件移入和移出我的 VM)。
尝试批量处理多个目录中的多张图片。我使用的是 imagemagick,它一次只能处理一个文件。
我希望它从顶级目录开始运行,然后对脚本可以找到的所有 jpg 文件执行此作业。
伪代码 -
for all folders in the directory
open folder
check if folder "drawings" (if !exists) then {start the loop over} else :
open drawings folder
for each file in drawings
if file is a jpg
run this program on it (convert image.jpg -crop 713x470+5+3 output.jpg)
答案1
弄清楚了我需要做什么循环,只需要掌握循环语法。希望这可以帮助其他可能需要根据名称循环遍历子目录的人。
for dir in */
do
for subdir in $PWD/"$dir"*/
do
if [ "$subdir" == $PWD/"$dir""Drawings"*/ ]
then
for file in "$subdir"*.jpg
do
rm "$file"
done
for file in "$subdir"*.pdf
do
newName="${file/.pdf/}"
convert -density 200 "$file" -append -resize 850 -background white -flatten "$newName".jpg
done
for file in "$subdir"*.jpg
do
newName="${file/.jpg/}"
if [[ "$file" == *"insulation"* ]]
then
convert "$file" -crop 820x710+15+97 "$newName-cropped.jpg"
else
convert "$file" -crop 820x870+15+79 "$newName-cropped.jpg"
fi
done
fi
done
done
exit 0
答案2
这就是我想出的
#!/bin/bash
dnames=$(for i in $(ls -d $1*/); do echo ${i}; done)
if [ "$#" -eq "1" ]; then
for dir in $dnames
do
cd $1
cd $dir
if [ -d "drawings" ]; then
cd drawings
jpgfiles=$(ls -p | grep -v / | awk '/.jp[e]?g/{print $0}')
if [ -z "$jpgfiles" ]; then
echo "Directory drawings exist in $dir but no .jpg images were found"
else
for jpgs in $jpgfiles
do
echo "found $jpgs in ${dir}drawings" #convert $jpgs -crop 713x470+5+3 output.jpg
done
fi
else
echo "Directory drawings cannot be found in $dir"
fi
done
else
echo "A full path to the directory must be given"
echo "For instance, /home/user1/Pictures/"
fi
这应该使用一个参数来运行,其中参数是目录的完整路径。例如,如果我要查找该图纸文件夹可能位于我的子目录中/主页/joram/目录
它会像这样
myprogram /home/joram/
程序循环/主页/joram/遍历其包含的所有目录。然后它访问/主页/joram/希望找到图纸子文件夹。当程序发现图纸包含 .jpg 图片的文件夹,命令就会被触发。完成命令后,只要检查完所有目录,程序就会继续循环。
程序输出示例:
#Directory drawings cannot be found in /home/joram/Desktop/
#Directory drawings cannot be found in /home/joram/Documents/
#Directory drawings exist in /home/joram/Downloads/ but no .jpg images were found
#Directory drawings cannot be found in /home/joram/Music/
#Directory drawings cannot be found in /home/joram/my_scripts/
#found test2.jpeg in /home/joram/Pictures/drawings
#found test.jpg in /home/joram/Pictures/drawings
#Directory drawings cannot be found in /home/joram/Public/
笔记:在当前形式下,该程序仅打印它找到的 .jpg 文件并提供一些其他信息(没有触发其他命令)。这样,可以在执行实际操作之前对其进行测试。要使程序获得您想要的内容,请删除 echo 部分并取消注释第 16 行的命令(如果这是您想要运行的实际命令)。
可以做出改进,希望这对您有所帮助!
答案3
算法是否必须完全相同,还是你只关心结果?因为我认为如果你使用find
目录遍历和搜索,你可以创建更短更简单的代码:
find /path/to/search-root -path '*/drawings/*.jpg' -execdir convert -crop 713x470+5+3 {} output.jpg \;
这将查找所有*.jpg
名为目录的(孙)子文件drawings
,并在这些文件上运行convert
命令。后者将output.jpg
在与源文件相同的目录中生成一个文件。如果同一目录中有多个源文件,则前一个output.jpg
实例将被覆盖。
如果您想要不同的、“唯一”的输出文件名,以便不覆盖之前的结果,则需要以某种方式转换输出文件名。不幸的是,我们find
无法做到这一点,但我们可以将该任务委托给 shell。有多种方法可以实现这一点,但我通常更喜欢管道而不是循环,while read
因为它比转义特殊字符更不烦人:
find /path/to/search-root -path '*/drawings/*.jpg' -print0 |
while IFS= read -rd '' f; do
convert -crop 713x470+5+3 "$f" "${f%.*}.output.jpg"
done
(这需要一个支持read -d
Bash 之类的 shell。如果您需要更便携的替代方案,请这么说。)