替换特定行和特定列上的字符

替换特定行和特定列上的字符

考虑这个sample.txt:

ATO   N   X B               
AT    H1  X BT              
ATOM H25  X BAA              
ATOM  H3  X BUTZ              
ATOM  CA  X BAT 

我想将第 2-4 行中的 X 替换为 awk 或其他内容的“A”,因此输出应该是:

ATO   N   X B               
AT    H1  A BT              
ATOM H25  A BAA              
ATOM  H3  A BUTZ              
ATOM  CA  X BAT 

我强调 X(或其替代品 A)是行中的第 11 个“实体”(包括字符或空格),并且应在输出中保留第 11 个“实体”,并且所有其他“实体”应保留在原始文件中的位置。

这个怎么做?谢谢

答案1

awk

awk 'BEGIN{ OFS=FS="" } FNR>=2 && FNR<=4 && $11=="X"{ $11="A" }1' sample.txt

使用空字符串作为输入和输出字段分隔符,如果该字段包含 ,则将第 11 个字段替换为输入文件的定义记录号X。然后打印记录。

答案2

一个简单的sed命令就可以完成这项工作:

sed '2,4s/ X / A /' your_file


cat foo.txt
ATO   N   X B               
AT    H1  X BT              
ATOM H25  X BAA              
ATOM  H3  X BUTZ              
ATOM  CA  X BAT 

sed '2,4s/ X / A /' foo.txt

ATO   N   X B               
AT    H1  A BT              
ATOM H25  A BAA              
ATOM  H3  A BUTZ              
ATOM  CA  X BAT 

正如 @Quasimodo 指出的,sed如果上面的命令遇到另一个像XThat's a GNU Awk 解决方案这样的序列,它就会失败:

awk 'NR >= 2 && NR <= 4 && $3~/X/ { sub(/X/, "A") } { print }' foo.txt

更新

非常感谢 @Quasimodo 这个命令:

sed '2,4s/^\(.\{10\}\)X/\1A/'

这确保只有第 11 个字符中出现的 X 才会被替换

答案3

使用awk,不一定是GNU,我们如图所示。首先根据范围选择行,然后通过尝试在第 11 个字符位置进行替换来进一步细化它们。

awk '(NR==2),(NR==4) {
    sub(/^.{10}X/, substr($0,1,10) "A")
}1' file

同样的事情在珀尔

perl -lpe 'substr($_,10,1) =~ s/X/A/ if 2..4' file

sed -e '
  2,4s/./&\n/11
  s/X\n/A/;s/\n//
' file

输入:

cat - <<\! > file
ATO   N   X B               
AT    H1  Q BT              
ATOM H25  X BA
ATOM  H3  X
ATOM  CA  X BAT 
!

结果:

ATO   N   X B               
AT    H1  Q BT              
ATOM H25  A BA
ATOM  H3  A
ATOM  CA  X BAT 

答案4

awk 'NR >1 && NR <5 {gsub("X","A",$3)}1' filename

输出

ATO   N   X B               
AT    H1  A BT              
ATOM H25  A BAA              
ATOM  H3  A BUTZ              
ATOM  CA  X BAT

相关内容