替换特定列中的值,同时保持原始格式不变

时间:2021-05-08 07:40:40

My input file have following format,

我的输入文件格式如下,

 ATOM      1 Cal  Cal     1      61.270  93.780 100.040  1.00  0.00
 ATOM      2 Cal  Cal     2      12.080  65.560 105.560  1.00  0.00
 ATOM     13 Cal  Cal    13      40.800  13.530  75.100  1.00  0.00
 ATOM    200 Cal  Cal   200     102.620  22.520  97.600  1.00  0.00

I would like to replace all the values in 8th-cloumn with value '32.450' while maintaining the original format (spacing) intact. i.e, the expected output should be like as shown below,

我希望用'32 .450'替换8th-cloumn中的所有值,同时保持原始格式(间距)不变。即,预期输出应如下所示,

 ATOM      1 Cal  Cal     1      61.270  93.780  32.450  1.00  0.00
 ATOM      2 Cal  Cal     2      12.080  65.560  32.450  1.00  0.00
 ATOM     13 Cal  Cal    13      40.800  13.530  32.450  1.00  0.00
 ATOM    200 Cal  Cal   200     102.620  22.520  32.450  1.00  0.00

I have tried with simple awk command

我尝试过简单的awk命令

awk -F " " '{ 
   print $1" " $2" "$3" "$4" "$5" "$6" "$7" "'32.450'" "$9" "$10" 
}' input.pdb > output.pdb

But, it failed preserve the original format.

但是,它无法保留原始格式。

Can anybody help me to find a better way to do this, preferably with awk or gawk?

任何人都可以帮助我找到更好的方法来做到这一点,最好是用awk或gawk?

3 个解决方案

#1


2  

GNU awk:

GNU awk:

gawk '
    BEGIN {FIELDWIDTHS="5 7 4 5 6 12 8 8 6 6"; OFS=""}
    {$8="  32.450"; print}
' file

input

输入

 ATOM      1 Cal  Cal     1      61.270  93.780 100.040  1.00  0.00
 ATOM      2 Cal  Cal     2      12.080  65.560 105.560  1.00  0.00
 ATOM     13 Cal  Cal    13      40.800  13.530  75.100  1.00  0.00
 ATOM    200 Cal  Cal   200     102.620  22.520  97.600  1.00  0.00

output

产量

 ATOM      1 Cal  Cal     1      61.270  93.780  32.450  1.00  0.00
 ATOM      2 Cal  Cal     2      12.080  65.560  32.450  1.00  0.00
 ATOM     13 Cal  Cal    13      40.800  13.530  32.450  1.00  0.00
 ATOM    200 Cal  Cal   200     102.620  22.520  32.450  1.00  0.00

#2


0  

If you have fixed width columns all the way through as in your sample input:

如果您在示例输入中一直有固定宽度列:

$ awk '{ print substr($0,1,47) " 32.450" substr($0,55) }' f.txt
ATOM      1 Cal  Cal     1      61.270  93.780  32.450  1.00  0.00
ATOM      2 Cal  Cal     2      12.080  65.560  32.450  1.00  0.00
ATOM     13 Cal  Cal    13      40.800  13.530  32.450  1.00  0.00
ATOM    200 Cal  Cal   200     102.620  22.520  32.450  1.00  0.00

#3


0  

Just tell sed to catch the first 7 blocks, skip the 8th and print the 7 back followed by 32.450.

告诉sed抓住前7个区块,跳过第8个区域并打印7个后面跟随32.450。

$  sed -r 's/(( +[^ ]+){7}) +[^ ]+/\1  32.450/' file
ATOM      1 Cal  Cal     1      61.270  93.780  32.450  1.00  0.00
ATOM      2 Cal  Cal     2      12.080  65.560  32.450  1.00  0.00
ATOM     13 Cal  Cal    13      40.800  13.530  32.450  1.00  0.00
ATOM    200 Cal  Cal   200     102.620  22.520  32.450  1.00  0.00

#1


2  

GNU awk:

GNU awk:

gawk '
    BEGIN {FIELDWIDTHS="5 7 4 5 6 12 8 8 6 6"; OFS=""}
    {$8="  32.450"; print}
' file

input

输入

 ATOM      1 Cal  Cal     1      61.270  93.780 100.040  1.00  0.00
 ATOM      2 Cal  Cal     2      12.080  65.560 105.560  1.00  0.00
 ATOM     13 Cal  Cal    13      40.800  13.530  75.100  1.00  0.00
 ATOM    200 Cal  Cal   200     102.620  22.520  97.600  1.00  0.00

output

产量

 ATOM      1 Cal  Cal     1      61.270  93.780  32.450  1.00  0.00
 ATOM      2 Cal  Cal     2      12.080  65.560  32.450  1.00  0.00
 ATOM     13 Cal  Cal    13      40.800  13.530  32.450  1.00  0.00
 ATOM    200 Cal  Cal   200     102.620  22.520  32.450  1.00  0.00

#2


0  

If you have fixed width columns all the way through as in your sample input:

如果您在示例输入中一直有固定宽度列:

$ awk '{ print substr($0,1,47) " 32.450" substr($0,55) }' f.txt
ATOM      1 Cal  Cal     1      61.270  93.780  32.450  1.00  0.00
ATOM      2 Cal  Cal     2      12.080  65.560  32.450  1.00  0.00
ATOM     13 Cal  Cal    13      40.800  13.530  32.450  1.00  0.00
ATOM    200 Cal  Cal   200     102.620  22.520  32.450  1.00  0.00

#3


0  

Just tell sed to catch the first 7 blocks, skip the 8th and print the 7 back followed by 32.450.

告诉sed抓住前7个区块,跳过第8个区域并打印7个后面跟随32.450。

$  sed -r 's/(( +[^ ]+){7}) +[^ ]+/\1  32.450/' file
ATOM      1 Cal  Cal     1      61.270  93.780  32.450  1.00  0.00
ATOM      2 Cal  Cal     2      12.080  65.560  32.450  1.00  0.00
ATOM     13 Cal  Cal    13      40.800  13.530  32.450  1.00  0.00
ATOM    200 Cal  Cal   200     102.620  22.520  32.450  1.00  0.00