Text 通过AWK在txt中进行基于模式的替换

Text 通过AWK在txt中进行基于模式的替换,text,awk,sed,Text,Awk,Sed,我有一个很长的文本文件,在靠近末尾的某个地方有一行,第三列==OXT ATOM 2439 O LEU 300 -4.699 34.599 65.335 1.00 83.23 O ATOM 2440 N LEU 301 -6.822 33.898 65.057 1.00 19.70 N ATOM 2441 CA LEU 301 -7.080 34.965 64.138 1

我有一个很长的文本文件,在靠近末尾的某个地方有一行,第三列==OXT

ATOM   2439  O   LEU   300      -4.699  34.599  65.335  1.00 83.23           O
ATOM   2440  N   LEU   301      -6.822  33.898  65.057  1.00 19.70           N
ATOM   2441  CA  LEU   301      -7.080  34.965  64.138  1.00 19.70           C
ATOM   2442  CB  LEU   301      -8.165  34.630  63.101  1.00 19.70           C
ATOM   2443  CG  LEU   301      -7.762  33.478  62.162  1.00 19.70           C
ATOM   2444  CD1 LEU   301      -8.849  33.207  61.110  1.00 19.70           C
ATOM   2445  CD2 LEU   301      -6.376  33.719  61.543  1.00 19.70           C
ATOM   2446  C   LEU   301      -7.556  36.168  64.946  1.00 19.70           C
ATOM   2447  O   LEU   301      -8.657  36.695  64.633  1.00 19.70           O
ATOM   2448  OXT LEU   301      -6.821  36.580  65.884  1.00 19.70           O
TER    2449      LEU   301
HETATM 2450 NA    NA   302     -13.016  13.036  54.214  1.00 44.33          NA
HETATM 2451  O   WAT   303     -18.411  13.587  59.094  1.00 27.41           O
HETATM 2452  O   WAT   304     -11.894  17.279  58.575  1.00 18.35           O
HETATM 2453  O   WAT   305     -15.811  12.728  54.157  1.00 39.81           O
我需要用模式OXT(参见下面的示例)以以下方式修改这一行:在第三列中,用“N”替换“OXT”;在第四列中,用NHE替换ACE;在最后一列中,将O替换为N。重要的是,在替换之后,我需要保持每列之间的空格数相等,与文件的其余部分相同:

ATOM   2439  O   LEU   300      -4.699  34.599  65.335  1.00 83.23           O
ATOM   2440  N   LEU   301      -6.822  33.898  65.057  1.00 19.70           N
ATOM   2441  CA  LEU   301      -7.080  34.965  64.138  1.00 19.70           C
ATOM   2442  CB  LEU   301      -8.165  34.630  63.101  1.00 19.70           C
ATOM   2443  CG  LEU   301      -7.762  33.478  62.162  1.00 19.70           C
ATOM   2444  CD1 LEU   301      -8.849  33.207  61.110  1.00 19.70           C
ATOM   2445  CD2 LEU   301      -6.376  33.719  61.543  1.00 19.70           C
ATOM   2446  C   LEU   301      -7.556  36.168  64.946  1.00 19.70           C
ATOM   2447  O   LEU   301      -8.657  36.695  64.633  1.00 19.70           O
ATOM   2448  N   NHE   301      -6.821  36.580  65.884  1.00 19.70           N
TER
HETATM 2450 NA    NA   302     -13.016  13.036  54.214  1.00 44.33          NA
HETATM 2451  O   WAT   303     -18.411  13.587  59.094  1.00 27.41           O
HETATM 2452  O   WAT   304     -11.894  17.279  58.575  1.00 18.35           O
HETATM 2453  O   WAT   305     -15.811  12.728  54.157  1.00 39.81           O
ATOM   2448  N   NHE   301      -6.821  36.580  65.884  1.00 19.70           N
我试着用

awk '$3=="OXT"{ f=1; rn=NR; $3=$NF="N"; $4="NHE" }/TER/ && f && NR-rn == 1{ $0=$1 }1' file
它产生了一个正确的作业,但在一个新字符串中,现在我在每列之间有1个空格,这是错误的格式

ATOM 2410 N NHE 299 -17.563 -15.711 -15.915 1.00 76.42 N
但是,我需要保持列之间间距的原始格式,与文件的其余部分相同:

ATOM   2439  O   LEU   300      -4.699  34.599  65.335  1.00 83.23           O
ATOM   2440  N   LEU   301      -6.822  33.898  65.057  1.00 19.70           N
ATOM   2441  CA  LEU   301      -7.080  34.965  64.138  1.00 19.70           C
ATOM   2442  CB  LEU   301      -8.165  34.630  63.101  1.00 19.70           C
ATOM   2443  CG  LEU   301      -7.762  33.478  62.162  1.00 19.70           C
ATOM   2444  CD1 LEU   301      -8.849  33.207  61.110  1.00 19.70           C
ATOM   2445  CD2 LEU   301      -6.376  33.719  61.543  1.00 19.70           C
ATOM   2446  C   LEU   301      -7.556  36.168  64.946  1.00 19.70           C
ATOM   2447  O   LEU   301      -8.657  36.695  64.633  1.00 19.70           O
ATOM   2448  N   NHE   301      -6.821  36.580  65.884  1.00 19.70           N
TER
HETATM 2450 NA    NA   302     -13.016  13.036  54.214  1.00 44.33          NA
HETATM 2451  O   WAT   303     -18.411  13.587  59.094  1.00 27.41           O
HETATM 2452  O   WAT   304     -11.894  17.279  58.575  1.00 18.35           O
HETATM 2453  O   WAT   305     -15.811  12.728  54.157  1.00 39.81           O
ATOM   2448  N   NHE   301      -6.821  36.580  65.884  1.00 19.70           N

您可以将命令的结果通过管道传输到
命令:

$>awk  '$3=="OXT"{ f=1; rn=NR; $3=$NF="N"; $4="NHE" }/TER/ && f && NR-rn == 1{ $0=$1 }1' f|column -t
ATOM    2439  O    LEU  300  -4.699   34.599  65.335  1.00  83.23  O
ATOM    2440  N    LEU  301  -6.822   33.898  65.057  1.00  19.70  N
ATOM    2441  CA   LEU  301  -7.080   34.965  64.138  1.00  19.70  C
ATOM    2442  CB   LEU  301  -8.165   34.630  63.101  1.00  19.70  C
ATOM    2443  CG   LEU  301  -7.762   33.478  62.162  1.00  19.70  C
ATOM    2444  CD1  LEU  301  -8.849   33.207  61.110  1.00  19.70  C
ATOM    2445  CD2  LEU  301  -6.376   33.719  61.543  1.00  19.70  C
ATOM    2446  C    LEU  301  -7.556   36.168  64.946  1.00  19.70  C
ATOM    2447  O    LEU  301  -8.657   36.695  64.633  1.00  19.70  O
ATOM    2448  N    NHE  301  -6.821   36.580  65.884  1.00  19.70  N
TER
HETATM  2450  NA   NA   302  -13.016  13.036  54.214  1.00  44.33  NA
HETATM  2451  O    WAT  303  -18.411  13.587  59.094  1.00  27.41  O
HETATM  2452  O    WAT  304  -11.894  17.279  58.575  1.00  18.35  O
HETATM  2453  O    WAT  305  -15.811  12.728  54.157  1.00  39.81  O
又快又脏:

#/bin/bash

skip=0
cat /tmp/list | while read line
do
  third=$(echo $line | awk '{print $3}')

  if [ $skip -eq 1 ]
  then
    echo "TER"
    skip=0
    continue
  fi

  if [ "${third}" == "OXT" ]
  then
    echo "${line}" | sed 's/OXT/N  /'
    skip=1
    continue
  fi

  echo "${line}"
done

当然,/tmp/list是包含所有值的文件。

相同的重复故事,它在替换字符串中生成正确的内容,但会破坏其余文件的某些部分:移动最后两列,从而生成人工制品。@m47730关于编辑:没有理由不能用不同的shell解决此问题。仅将答案限制为bash将是不必要的限制。下面用bash编写的注释中的脚本非常有效!!!它是bash和sed的组合!它在替换字符串中生成正确的输出,但会破坏原始文件其余部分的某些部分,在某些部分,最后两列被移动甚至合并在一起,从而生成错误的输出文件。可能与
fmt
耦合,或使用
-c
选项?这样它就不起作用了awk'$3==“OXT”{f=1;rn=NR;$3=$NF=“N”;$4=“NHE”}/TER/&f&&NR rn==1{$0=$1}1'文件|列-t | fmtThanks!通常它工作正常。但是如何向sed添加一个额外的脚本来替换第四列(NHE上的任何树大写字母)和最后一列(将O替换为N)中的值。类似于第四列(不幸的是,它也替换了同一字符串的第1列,这是不好的):sed-e's/OXT/N/'-e's/[[:upper:][[:upper:][[:upper:]]/NHE/g'@JamesStarlight用这个新问题更新你的问题;这一次也放上输入和预期的输出。以这种描述方式,我真的不确定能达到你的目标。