Text 通过AWK在txt中进行基于模式的替换
我有一个很长的文本文件,在靠近末尾的某个地方有一行,第三列==OXTText 通过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
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用这个新问题更新你的问题;这一次也放上输入和预期的输出。以这种描述方式,我真的不确定能达到你的目标。