使用Bash脚本在子文件夹中执行ImageMagick转换

使用Bash脚本在子文件夹中执行ImageMagick转换,bash,shell,imagemagick,imagemagick-convert,Bash,Shell,Imagemagick,Imagemagick Convert,我有多个JPEG系列。每个系列都在自己的文件夹中。我希望将每个系列转换为单个pdf。我还希望pdf与它所在的文件夹同名 要在每个文件夹的命令行上执行此操作,我可以使用以下命令: convert *.jpg `echo ${PWD##*/}`.pdf 我想用bash脚本从顶层文件夹中执行它 您可能需要使用find进行以下操作: find . -type d -exec bash -c 'cd "$0" || exit; shopt -s nullglob; f=( *.jpg ); ((${#f

我有多个JPEG系列。每个系列都在自己的文件夹中。我希望将每个系列转换为单个pdf。我还希望pdf与它所在的文件夹同名

要在每个文件夹的命令行上执行此操作,我可以使用以下命令:

convert *.jpg `echo ${PWD##*/}`.pdf

我想用bash脚本从顶层文件夹中执行它

您可能需要使用
find
进行以下操作:

find . -type d -exec bash -c 'cd "$0" || exit; shopt -s nullglob; f=( *.jpg ); ((${#f[@]})) && echo convert "${f[@]}" "${PWD##*/}.pdf"' {} \;
这将递归到每个子目录,并为每个子目录执行Bash命令:

cd "$0" || exit
shopt -s nullglob
f=( *.jpg )
((${#f[@]})) && echo convert "${f[@]}" "${PWD##*/}.pdf"
  • $0
    将扩展到给定给Bash的参数,即
    find
    找到的目录。
    exit
    在这里是一种安全措施,以防
    cd
    无法进入:在这种情况下,您不希望执行随机命令
  • shopt-s nullglob
    :如果没有匹配项,glob将扩展为零。如果子目录中没有以
    .jpg
    结尾的文件名,则此选项非常有用
  • 构建当前目录中所有文件名的数组
    f
    ,文件名以
    .jpg
    结尾。如果没有此类文件,则此数组为空(由于
    nullglob
    shell选项)
  • 如果数组
    f
    为非空,请执行以下命令:

    echo convert "${f[@]}" "${PWD##*/}.pdf"
    
    (顺便说一下,您的
    echo${PWD##*/}.pdf
    是错误的,请参见下文)

我把一个
回音
放在
转换
的前面,这样实际上什么也没有执行;该命令显示在标准输出上,供您目视检查是否一切正常。如果是这种情况,只需卸下回声


你在评论中问道:为什么你说下面这句话是错的

convert *.jpg `echo ${PWD##*/}`.pdf
你甚至说因为它起作用了。在计算机科学中,工作和正确是不平等的。it-works句子应该完全理解为以下形式:it-works直到失败。最明显的失败情况是,如果目录名包含空格:假设目录名为
hello world
,则convert会将
hello
单独视为一个参数,将
world.pdf
视为最后一个参数。很可能不是你想要的。此外,以下内容正确(且简短易懂):


这很有效,非常感谢。我有一个问题:1。我不明白你说我的“echo${PWD#*/}.pdf”是错的,因为它起作用了。你能解释一下吗?如果有人想在脚本中加入此内容,只需在一行“#”后粘贴即可/“bin/bash”,它工作得很好。@Jack补充了一个小说明,说明了为什么你的回声部分是错误的。
convert *.jpg "${PWD##*/}.pdf"