如何使用 shell 脚本在与 txt 文件的条件匹配的行上的特定列上附加字符串?



我有一个带有一堆序列号的文本文件,它们应该有 16 个字符长。但有些记录已损坏,长度为 13 个字符。我想在每条长度为 13 个字符的记录的开头添加 3 个零。

注意:序列号不是从行首开始的,它们都从每行的第 15 列开始。

我的文件目前如下所示:

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:             :              

这是我为获取缩短的记录而编写的代码:

#!/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

txt 文件有超过 50,000 条记录,所以我无法手动更改它们。

这个sed单行应该可以完成这项工作:

sed 's/^(.{14})([0-9]{13}[^0-9])/10002/' file

这假定序列号仅由十进制数字组成,并相信它们都从行的第 15 个字符开始。

或者,一个awk解决方案:

awk 'BEGIN { FS=OFS=":" } length($6) == 13 { $6 = "000" $6 } 1 ' file

这只检查第六个字段的长度是否为 13,并信任第六个字段是序列号字段。

一个awk想法,它取代了OP的所有当前代码:

awk '
BEGIN         { FS=OFS=":" }                # set input/output field delimiter to ":"
length($6)<16 { $6=sprintf("%016d",$6) }    # if length of 6th field < 16 then left-pad the field with 0's to length of 16
1                                           # print current line
' file.txt

这将生成:

1:6822:26: :A:0000000000999993:DIS:14516E : :01: : : ::0529483733710: : :
1:6822:26: :A:0000000000999994:MAT:13L324 : :01: : : :: : : :
1:6822:26: :A:0000000000999995:CAT:P13WFB : :01: : : ::0529483697940: : :
1:6822:26: :3:0000000000170891: :AZDG-2 :0000003999:01:0000000000: : :: : : :
1:6822:26: :3:0000000000170892: :AZDG-3 :0000003999:01:0000000000: : :: : : :
1:6822:26: :3:0000000000170893: :AZDG-4 :0000003999:01:0000000000: : :: : : :

我冒昧:

在...
$ awk '{if(length($2)<19){$2=gensub(/^(:.:)/,"\1000","1",$2)":"}}1' file.txt 
1:6822:26: :A:0000000000999993: :DIS:14516E : :01: : : ::0529483733710: : :
1:6822:26: :A:0000000000999994: :MAT:13L324 : :01: : : :: : : :
1:6822:26: :A:0000000000999995: :CAT:P13WFB : :01: : : ::0529483697940: : :
1:6822:26: :3:0000000000170891: :AZDG-2 :0000003999:01:0000000000: : :: : : :
1:6822:26: :3:0000000000170892: :AZDG-3 :0000003999:01:0000000000: : :: : : :
1:6822:26: :3:0000000000170893: :AZDG-4 :0000003999:01:0000000000: : :: : : :

如果这不是您想要的,请使用以下内容:awk '{if(length($2)<19){$2=gensub(/^(:.:)/,"\1000","1",$2)}}1' file.txt

另一种选择

awk -v{O,}FS=: '{$6=gensub(" ", "0", "g", sprintf("%16s", gensub(" ", "", "g", $6)))}1'

结果

1:6822:26: :A:0000000000999993:DIS:14516E : :01: : : ::0529483733710: : :
1:6822:26: :A:0000000000999994:MAT:13L324 : :01: : : :: : : :
1:6822:26: :A:0000000000999995:CAT:P13WFB : :01: : : ::0529483697940: : :
1:6822:26: :3:0000000000170891: :AZDG-2 :0000003999:01:0000000000: : :: : : :
1:6822:26: :3:0000000000170892: :AZDG-3 :0000003999:01:0000000000: : :: : : :
1:6822:26: :3:0000000000170893: :AZDG-4 :0000003999:01:0000000000: : :: : : :

相关内容

  • 没有找到相关文章

最新更新