我想在所有子目录中的每个 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 {} +