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

使用pdfgrep排序文件时bash脚本卡住及运行缓慢问题咨询

问题修复与性能优化方案

输出卡顿、按Ctrl+C才批量打印日志的根因

  • 管道块缓冲:Linux下程序输出走管道时默认使用4KB大小的块缓冲,而非面向终端的行缓冲。原脚本中pdfgrep的输出通过管道传给xargs,匹配到的文件名会攒到缓冲满才会输出,无法实时打印进度。
  • Shell通配符阻塞:原脚本写的$HOME/PDFs/*会先由Shell展开目录下所有文件名,若目录下文件数量过万,这个展开过程会持续数秒到数分钟,期间无任何输出,表现为进程卡住。
  • 执行逻辑无中间输出:原脚本用xargs -I{}会等待pdfgrep完成全目录扫描、拿到所有匹配结果后才会执行复制操作,整个扫描阶段没有进度反馈。

执行耗时过长的根因

  • 重复IO开销:原逻辑每匹配一个关键词,就要完整遍历、解析一遍所有PDF文件,关键词数量和耗时线性增长,是性能差的核心原因。
  • 进程冗余开销:xargs -I{} cp {}语法每匹配到一个文件就启动一次cp进程,文件量大时进程创建、销毁的开销占比极高。
  • 无效扫描:未指定只扫描PDF后缀文件,目录下的非PDF文件也会被pdfgrep尝试解析,浪费算力。
  • 重复递归:传入通配符展开的文件列表同时加-r递归参数,会导致子目录被重复遍历。

修复后优化脚本

#!/bin/bash
set -euo pipefail

# 关键词列表
keywords=(
    "Keyword1"
    "Keyword2"
    "Keyword3"
);

# -p 参数自动创建不存在的目录,目录已存在时不报错
mkdir -p "$HOME/Sorted";
echo "匹配任务启动,共加载 ${#keywords[@]} 个关键词";

# 提前创建所有关键词对应的输出目录,构造pdfgrep多模式匹配参数
grep_args=()
for kw in "${keywords[@]}"; do
    grep_args+=(-e "$kw")
    mkdir -p "$HOME/Sorted/$kw"
done

echo "开始扫描PDF目录...";
# 核心优化说明:
# 1. 直接传入目录路径给pdfgrep,不使用Shell通配符展开,避免大目录下展开卡顿、参数过长报错
# 2. -l 仅输出匹配到的文件名,-i 忽略大小写,-r 递归遍历子目录
# 3. --include=*.pdf 仅扫描PDF后缀文件,跳过无关文件
# 4. -F 将关键词作为固定字符串匹配(若关键词为正则表达式请删除该参数),匹配速度比正则快30%以上
# 5. stdbuf -oL 强制pdfgrep使用行缓冲,匹配到结果立刻输出,解决日志卡顿问题
# 6. 逐行读取匹配结果,批量处理文件,减少不必要的进程开销
stdbuf -oL pdfgrep -lirF --include=*.pdf "${grep_args[@]}" "$HOME/PDFs/" | while read -r matched_file; do
    # 检查当前文件命中的关键词,复制到对应目录
    for kw in "${keywords[@]}"; do
        if pdfgrep -qF "$kw" "$matched_file"; then
            # -n 参数不覆盖已存在的同名文件,需要覆盖请删除该参数
            cp -n "$matched_file" "$HOME/Sorted/$kw/"
        fi
    done
done

echo "匹配任务执行完成";
echo "###########################";
echo "未匹配到任何文件的关键词:";
find "$HOME/Sorted/" -type d -empty -printf "%P\n";
find "$HOME/Sorted/" -type d -empty -delete;

额外说明

  • 如果PDF是扫描生成的图片版PDF,pdfgrep无法直接识别内容,需要先做OCR文字识别才能检索,和脚本逻辑无关。
  • 如果关键词数量超过10个,可以把关键词单独写到一个文本文件里,用pdfgrep -f 关键词文件路径的方式加载,比写在数组里更易维护。

内容的提问来源于stack exchange,提问作者Bart

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 06:03:12