如何在同一sed脚本中读写临时文件?附PDF转码场景问题
问题解答
1. 同一sed脚本中读写文件的可行性与缓存问题
GNU sed 4.7支持在同一脚本里完成文件的写入和读取,但你遇到的读取失败问题,根源是sed的w命令默认采用缓冲写入机制——写入的内容会先暂存到内存缓存,不会立刻同步到磁盘。当你紧接着用r命令读取该文件时,磁盘上的文件还未更新,自然读不到最新内容。
强制同步缓存的两种解决方法
- 方法一:使用GNU sed原生
flush命令
你的sed版本4.7满足GNU sed 4.2及以上的要求,可以直接用flush命令强制将缓存内容刷到磁盘:/regex to last fix/ { n; p; n; w rtcol.txt flush rtcol.txt # 强制同步缓存到磁盘 r rtcol.txt } - 方法二:调用shell的
sync命令
通过sed的!执行外部shell命令,强制同步目标临时文件:
若担心/regex to last fix/ { n; p; n; w rtcol.txt !sync rtcol.txt # 调用shell同步文件到磁盘 r rtcol.txt }sync同步整个文件系统缓存的性能影响,也可以用!dd conv=fdatasync of=rtcol.txt(需确保文件已存在),但注意这种方式需要额外处理命令执行的输出。
2. 更优替代方案:改用awk处理
如果你的场景涉及多种复杂的文本修正逻辑,awk会比sed更适配:
- awk的文件操作是实时写入磁盘,不存在缓冲延迟问题;
- 支持自定义变量存储状态(比如左栏、右栏的内容缓冲区),无需依赖外部临时文件;
- 处理多行文本、正则捕获的逻辑更直观,代码可读性和维护性更高。
举个简化的awk思路示例:
# 处理连字符导致的左右栏混排 /hyphen-trigger-pattern/ { # 提取左栏内容并输出到stdout split_pos = index($0, "-") - 2 ltcol = substr($0, 1, split_pos) print ltcol # 提取右栏内容存入缓冲区 rtcol_buf = rtcol_buf "\n" substr($0, split_pos + 4) next } # 处理已分离的左栏+右栏行 /ltcol-line-pattern/ { print $0 # 直接输出左栏 getline # 读取下一行的右栏内容 rtcol_buf = rtcol_buf "\n" $0 next } # 脚本结束时输出所有缓存的右栏内容 END { print rtcol_buf }
3. 额外优化建议
- 优先调整pdftotext参数:尝试添加
-layout参数强制保留页面布局,可能从源头减少双栏混排的问题,降低后续修正的复杂度; - 避免sed过度依赖外部文件:sed的设计核心是流式文本处理,复杂的多状态、文件读写场景会让脚本逻辑变得冗余且难以维护。
内容的提问来源于stack exchange,提问作者Tyrone Mosley
相关产品推荐
相关产品推荐

