递归压缩 PDF - 在目录和子目录中查找 PDF 并执行脚本

递归压缩 PDF - 在目录和子目录中查找 PDF 并执行脚本

我想在所有子目录中的每个 PDF 上执行一个脚本,但文件名包含空格时会出现问题。我搜索了很多,这个帖子似乎是一个解决方案,但我找不到使我的脚本正常运行的方法。

在文件夹中,这非常有效:

for f in *.pdf;  do
    filename=$(basename -- "${f}") && extension="${filename##*.}" && filename="${filename%.*}" && outpt="$filename-compressed.pdf"
    echo "$filename"
    echo "$outpt"
    gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook -dNOPAUSE \
    -dQUIET -dBATCH -sOutputFile="$outpt" "${f}";
    # rm "${f}";
done;

然后我尝试递归搜索(在添加“gs -sDEVICE=pdfwrite ......”之前)

for f in $(find "$(pwd)" -name '*.pdf'); do 
    filename=$(basename -- "${f}") && extension="${filename##*.}" && filename="${filename%.*}" && outpt="$filename-compressed.pdf"
    echo "$filename"
    echo "$outpt"
done

但我无法正确获取文件名。可能是因为文件名中有空格?

如果您有想法的话非常感谢您的帮助!

------------------ 已解决 感谢@steeldriver

find . -name '*.pdf' -execdir sh -c '
for f do
    filename=${f##*/} && extension=${f##*.} \
        && filename=${filename%.*} && outpt=$filename-compressed.pdf
    gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook -dNOPAUSE -dQUIET -dBATCH -sOutputFile="$outpt" "$filename.pdf"; 
    echo "$filename"
    echo "$outpt"
    # rm "$filename.pdf" # remove original
done' find-sh {} +

答案1

是的,for filename in将会吐出当前IFS变量中的字符 - 默认情况下,是空格、制表符和换行符。

虽然您可以使用 find-print0并使用空分隔xargs或空分隔的 shellwhile循环读取结果,但您也可以使用 find-exec-execdir通过其位置参数将文件名明确地传递给 shell 命令:

find . -name '*.pdf' -exec sh -c '
  for f do 
    filename=${f##*/} && extension=${f##*.} \
      && filename=${filename%.*} && outpt=$filename-compressed.pdf
    echo "$filename"
    echo "$outpt"
  done' find-sh {} +

相关内容