You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用qpdf和Perl为PDF文件名添加页数前缀/后缀时脚本执行异常求助

使用qpdf和Perl为PDF文件名添加页数前缀/后缀时脚本执行异常求助

兄弟,我先理清楚你的问题:你用sed提取PDF文件名的基础部分和括号里的数字时,简化脚本完全正常,但一结合qpdf(或者更复杂的逻辑),脚本就重复输出文件名三次,比如File (11).pdf连打三遍,对吧?

首先可以排除是sed正则的问题——毕竟你已经验证了简化版的提取逻辑没问题,大概率是循环的输入来源或者变量处理出了坑,我给你拆解几个常见问题和解决方案:

1. 别用ls *.pdf遍历文件!

虽然你设置了IFS=$'\n',但ls的输出在处理带空格/特殊字符的文件名时,很容易出各种意外(比如隐形的换行、拆分)。直接用通配符遍历才是稳妥的写法:

IFS=$'\n'
# 直接遍历当前目录的所有PDF,不需要调用ls
for i in *.pdf; do
    # 你的处理逻辑
done

这个小改动就能避免很多莫名其妙的循环重复问题。

2. 检查qpdf的输出是否干净

如果你的复杂脚本里用了qpdf获取页数(比如qpdf --show-npages "$i"),要确认它只输出数字,没有多余的警告、错误信息。如果qpdf输出了多行内容,会导致变量里混入换行,进而让后续逻辑重复执行。你可以单独跑一遍qpdf --show-npages "File (11).pdf"看看输出是不是只有一个数字。

3. 变量引用一定要加双引号!

你简化脚本里的printf $i其实有隐患,如果文件名里有空格或特殊字符,会被shell拆分。正确的写法是printf "%s\n" "$i",加双引号能保证变量被当成一个整体处理,避免意外拆分导致的重复输出。

给你一个调试后的完整示例(假设你要结合页数重命名)

如果你的需求是把File (11).pdf改成类似File_11_5.pdf(5是页数),可以用这个脚本:

# 遍历当前目录所有PDF文件
for pdf_file in *.pdf; do
    # 提取基础文件名(去掉括号数字和.pdf后缀)
    base_name=$(echo "$pdf_file" | sed -E 's/^(.*)( \([0-9]{1,4}\))(\.pdf)$/\1/')
    # 提取括号里的数字并去掉括号和空格
    seq_num=$(echo "$pdf_file" | sed -E 's/^(.*)( \([0-9]{1,4}\))(\.pdf)$/\2/' | tr -d '() ')
    # 获取PDF页数(确保qpdf只输出数字)
    page_count=$(qpdf --show-npages "$pdf_file")
    # 重命名文件(按需调整格式)
    mv "$pdf_file" "${base_name}_${seq_num}_${page_count}.pdf"
    # 输出处理结果验证
    echo "已处理:$pdf_file → ${base_name}_${seq_num}_${page_count}.pdf"
done

快速定位问题的小技巧

你可以在复杂脚本的循环开头加一句echo "当前正在处理:$i",看看循环到底执行了几次,每次的$i是什么值。如果循环执行了三次,那就是遍历的元素多了;如果只执行一次但输出三次,那就是后面的printf或其他命令重复调用了。

备注:内容来源于stack exchange,提问作者Brian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.16 09:34:35