linux 替换前3个字符范围内的所有整数

bkhjykvo  于 2023-03-07  发布在  Linux
关注(0)|答案(3)|浏览(130)

我在example文件中有一个ID列表,如下所示:

3SN0P00000026941
14N0P00000026677
6SN0P00000024671
3SN0P00000018643

我想输出的内容如下所示:

ENSN0P00000026941 3
ENSN0P00000026677 14
ENSN0P00000024671 6
ENSN0P00000018643 3

它基本上从每行的前3个字符范围内提取所有整数,分别替换为“ENS”或“EN”,例如前3个字符中有1个整数,就会替换为“EN”;如果有2个整数,则替换为“ENS”。
问题是我不知道如何执行这样一个替换,即只针对前3个字符范围内的整数,并根据存在的整数数量将其替换为“EN”或“ENS”。我尝试使用sedsed 's/^.../ENS/g',输出与原始列表相比没有任何差异。
是否有代码或脚本可以执行这样的过程?例如使用awksed或其他函数?

ijxebb2r

ijxebb2r1#

使用sed

$ sed -E 's/^([0-9]{1,2})S?(.*)/ENS\2 \1/' input_file
ENSN0P00000026941 3
ENSN0P00000026677 14
ENSN0P00000024671 6
ENSN0P00000018643 3
gkl3eglg

gkl3eglg2#

我将按照以下方式利用GNU AWK完成此任务,让file.txt内容

3SN0P00000026941
14N0P00000026677
6SN0P00000024671
3SN0P00000018643

那么

awk '{two=/^[0-9][0-9]/;print (two?"ENS":"EN") substr($0,two?3:2) " " substr($0,1,two?2:1)}' file.txt

给出输出

ENSN0P00000026941 3
ENSN0P00000026677 14
ENSN0P00000024671 6
ENSN0P00000018643 3

说明:如果two至少有2个前导数字,则将其设置为1,否则为0。然后使用所谓的三元运算符(条件:值为真?值为假)和substr函数,根据该值打印print,打印的是以下元素的连接

  • ENS,如果为两个,则为EN
  • 从第3个字符开始的行的一部分,如果还有两个从第2个字符开始
  • 空格字元
  • 前两个字符,如果还有两个则前一个字符
  • (在GNU Awk 5.0.1中测试)*
lbsnaicq

lbsnaicq3#

达到相同效果的4种不同方式:

mawk 'sub("^[^N]+", "ENS", $!($++NF += $+_))_'
 gawk 'sub("^[^N]+", "ENS", $+_^($++NF += $!_))_'
 nawk 'sub("^[^N]+", "ENS", $(_*($++NF += $-_)))_'
 mawk 'sub("^[^N]+", "ENS", $(_~($++NF = +$+_)))^_'
ENSN0P00000026941 3
ENSN0P00000026677 14
ENSN0P00000024671 6
ENSN0P00000018643 3

.....并在awk组合中进行了测试:
一个二个一个一个

相关问题