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

Shell脚本批量修复指定列13位序列号:前缀补3个0

批量修复指定位置的短序列号

我有一个包含5万多条记录的文本文件,其中序列号从每行第15列开始,正常长度为16字符,但部分损坏成了13字符。需要给所有13位的序列号开头补3个0,使其恢复为16位长度。

原文件示例

1:CCCC:CC: :C:0000000999993:   :CCC:             :          
1:CCCC:CC: :C:0000000999994:   :CCC:             :          
1:CCCC:CC: :C:0000000999995:   :CCC:             :          
1:CCCC:CC: :C:0000000000170891:   :CCC:             :
1:CCCC:CC: :C:0000000000170892:   :CCC:             :      
1:CCCC:CC: :C:0000000000170893:   :CCC:             :              

期望输出

1:CCCC:CC: :C:0000000000999993:   :CCC:             :          
1:CCCC:CC: :C:0000000000999994:   :CCC:             :          
1:CCCC:CC: :C:0000000000999995:   :CCC:             :          
1:CCCC:CC: :C:0000000000170891:   :CCC:             :
1:CCCC:CC: :C:0000000000170892:   :CCC:             :      
1:CCCC:CC: :C:0000000000170893:   :CCC:             :              

我之前写了一段bash脚本只能筛选出短记录,但无法直接修改原文件:

#!/bin/bash
i=1
for OUTPUT in $(cut -c15-30 file.txt)
do
   if [[ ${#OUTPUT} == 13 ]]
   then 
          echo $OUTPUT
          echo $i
          i=$((i+1))
    
   fi
done

高效解决方案

针对大文件,推荐用awk或sed处理,它们都是流式文本工具,内存占用低、处理速度快,适合5万+行的场景。

方法1:用awk按列位置处理

这个方法不依赖字段分隔符,严格按照第15列的起始位置处理,兼容性更强:

awk '{
    # 提取前14个字符作为前缀
    head = substr($0, 1, 14)
    # 提取从第15位开始的剩余内容
    tail = substr($0, 15)
    # 匹配开头的数字序列(即序列号)
    match(tail, /^[0-9]+/)
    serial = substr(tail, RSTART, RLENGTH)
    # 如果序列号长度是13,补3个0
    if (length(serial) == 13) {
        new_tail = "000" serial substr(tail, RSTART+RLENGTH)
    } else {
        new_tail = tail
    }
    # 拼接并输出完整行
    print head new_tail
}' file.txt > fixed_file.txt

方法2:用sed简洁处理(适用于纯数字序列号)

如果确认序列号是纯数字,且后面紧跟非数字字符(比如示例中的:),可以用更简洁的sed命令:

sed -E 's/^(.{14})([0-9]{13})([^0-9])/\1000\2\3/' file.txt > fixed_file.txt

命令解释:

  • ^(.{14}):匹配前14个字符并保存
  • ([0-9]{13}):匹配接下来的13位数字(短序列号)并保存
  • ([^0-9]):匹配序列号后的第一个非数字字符并保存
  • 替换为\1000\2\3:在前14个字符后添加000,再拼接原序列号和后续内容

原脚本的问题说明

你之前的bash脚本存在两个明显问题:

  1. 语法错误:for OUTPUT in $*(cut ...) 应该是$(cut ...),否则会把cut当作参数传递给当前脚本的参数列表
  2. 效率低且功能有限:循环遍历cut的输出时,若内容包含空格会被拆分,导致判断错误;而且只能筛选无法修改原文件,不适合大规模处理。

内容的提问来源于stack exchange,提问作者Luis Meléndez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 20:15:42