60MB路径文件处理Shell脚本性能优化求助
优化大文件路径处理脚本的性能
问题根源
你的脚本速度慢的核心原因是每次生成填充点时调用了seq和tr两个外部命令。对于每一行长度不足100字符的路径,都要启动两个独立子进程,60MB的文件包含大量行,累计的进程创建开销直接拖慢了整个处理流程。更新后的while read版本解决了一次性读取大文件到变量的问题,但生成填充符的子进程开销仍然存在,所以速度还是不够理想。
优化方案一:用Bash内置操作替换外部命令
预先生成足够长的点字符串,之后通过内置字符串截取获取需要的填充长度,完全避免外部命令调用:
#!/bin/bash # 预先生成100个点的字符串,满足最大补全需求 full_dots=$(printf '%.s.' {1..100}) while IFS= read -r line; do line_len=${#line} if (( line_len > 100 )); then # 截取最后100个字符 echo "${line:line_len-100}" else # 从预生成的点串中截取对应长度的填充符 filler="${full_dots:0:100 - line_len + 1}" echo "${filler}${line}" fi done < "$HOME/plocate-index.txt" > "$HOME/plocate-index-fixed.txt"
这个版本将填充符生成逻辑改为Bash内置操作,消除了循环中的子进程开销,处理速度会有明显提升。
优化方案二:用Awk处理(性能最优)
Awk是专为文本流设计的高效处理工具,内部逻辑由C实现,比Bash循环快几个量级,适合大文件批量处理:
#!/usr/bin/awk -f BEGIN { # 预先生成100个点的填充串 full_dots = sprintf("%100s", "") gsub(/ /, ".", full_dots) } # 路径长度超过100,截取最后100个字符 length($0) > 100 { print substr($0, length($0) - 99) next } # 路径长度不足100,补全点字符 { fill_len = 100 - length($0) + 1 print substr(full_dots, 1, fill_len) $0 }
使用方式:将上述代码保存为process_paths.awk,然后运行:
awk -f process_paths.awk "$HOME/plocate-index.txt" > "$HOME/plocate-index-fixed.txt"
或者直接使用单行命令:
awk 'BEGIN{full_dots=sprintf("%100s","");gsub(/ /,".",full_dots)}length($0)>100{print substr($0,length($0)-99);next}{fill_len=100-length($0)+1;print substr(full_dots,1,fill_len)$0}' "$HOME/plocate-index.txt" > "$HOME/plocate-index-fixed.txt"
Awk的优势在于整个处理过程在单个进程内完成,没有循环中的子进程开销,处理60MB文件的速度可以和生成索引的速度(约2秒)匹配。
内容的提问来源于stack exchange,提问作者Ahmad Ismail
相关产品推荐
相关产品推荐

