枚举对象列表

Tom*_*mba -1 awk text-processing

我有一个对象列表,它们的名称具有相同的格式(*_region_NNN 其中*表示变量名称和NNN数字)。我需要以相同的顺序获取相同的列表,但使用序列号修改名称的数字部分。对象按字母顺序排序。所有同名 ( *) 的对象必须从 001 开始按顺序编号

列表.txt:

BIRC2_region_087
BIRC2_region_089
BIRC2_region_114
BMI1_region_193
BMI1_region_243
CRBN_region_109
CRBN_region_134
CRBN_region_145
CDC20_region_001
CDC20_region_002
CDC20_region_004
CBL_region_002
CBL_region_003
CBL_region_004
CBL_region_005
CBL_region_006
CBL_region_008
CBL_region_009
CBL_region_024
CBL_region_033
CBL_region_042
CBL_region_048
CBL_region_075
CBL_region_076
CBL_region_086
CBL_region_111
CBL_region_112
CBL_region_146
CBL_region_172
CBL_region_248
CBL_region_252
Run Code Online (Sandbox Code Playgroud)

输出.txt

BIRC2_region_001
BIRC2_region_002
BIRC2_region_003
BMI1_region_001
BMI1_region_002
CRBN_region_001
CRBN_region_002
CRBN_region_003
CDC20_region_001
CDC20_region_002
CDC20_region_003
CBL_region_001
CBL_region_002
CBL_region_003
CBL_region_004
CBL_region_005
CBL_region_006
CBL_region_007
CBL_region_008
CBL_region_009
CBL_region_010
CBL_region_011
CBL_region_012
CBL_region_013
CBL_region_014
CBL_region_015
CBL_region_016
CBL_region_017
CBL_region_018
CBL_region_019
CBL_region_020
Run Code Online (Sandbox Code Playgroud)

有人可以帮我吗?

αғs*_*нιη 5

使用awk不需要将全部/部分输入数据缓冲到内存中(因为您提到的数据已经排序):

awk -F'_[^_]*$' 'pre!=$1{ id=0 }
{ pre=$1; printf("%s_%03d\n", $1, ++id) }' infile
Run Code Online (Sandbox Code Playgroud)

随着_[^_]*$我们定义了最后_<zero-or-more-of-any-characters-but-not-underscore><end-of-line>的现场分隔符。

[^_]表示除下划线外的任何单个字符(换行符也例外);并[^_]*表示 <zero-or-more-of-any-characters-but-not-underscore>,$即 <end-of-line> 锚点。

如果剩余行的一部分(可通过 访问$1)与前一行不同,则将 id 计数重置为 0,否则打印$1和增量 ids 并带有 3 个前导零。


动态零填充控制:

<infile awk -F'_[^_]*$' '{ print $1 }' \
|sort |uniq -c |sort -r \
|awk 'NR==1{ z=length($1) } { for(i=1; i<=$1; i++) printf("%s_%0*d\n", $2, z, i) }'
Run Code Online (Sandbox Code Playgroud)