unix:用另一个文件中的单个值替换一个文件中的一整列

unix:用另一个文件中的单个值替换一个文件中的一整列

我想使用 unix 将一个文件中的列替换为另一个文件中的单个值。

文件1是一个pdb文件,结构如下:

HETATM   14  H4B FAD B 600      95.544  50.240  71.308  1.00 -1.00 H  
HETATM   14  H4B FAD B 600      95.544  50.240  71.308  1.00 -1.00 H  

我想用存储在另一个文件(文件 2)中的单个值替换第 11 列,如下所示:

[1, 27, -81.883, 4.0]
[3, 38, -66.122, 12.0]
[3, 57, -62.134, 12.0]

我希望文件 2(第 1 行第 3 列)中的值成为文件 1 第 11 列中的值,以便文件 1 如下所示:

HETATM   14  H4B FAD B 600      95.544  50.240  71.308  1.00 -81.88 H  
HETATM   14  H4B FAD B 600      95.544  50.240  71.308  1.00 -81.88 H

我可以使用以下命令将文件 1 的第 11 列替换为单个值(本例中为 2):

awk '{$11=2}1' File1

我找到了类似这样的代码https://stackoverflow.com/questions/7846476/replace-column-in-one-file-with-column-from-another-using-awk

awk 'FNR==NR{a[NR]=$3;next}{$2=a[FNR]}1' f2 f1

不过,我相信我应该使用 awk 和 sed 的组合来将我想要的值从文件 2 中获取到文件 1 中。

下面的代码给出了第 11 列的第一行:

awk 'FNR==1{print $11}'

我根本不知道如何将这两件事结合起来。

我无法按值搜索,因为值会随着我拥有的每个数据集而变化(需要修改数百个 pdb 文件)。

有人可以帮忙吗?

下面的两个解决方案都搞乱了我的 pdb 文件的格式,这意味着我得到:

HETATM 1 PA FAD B 600 95.887 47.194 74.387 1.00 -73.248 

代替

HETATM    1  PA  FAD B 600      95.987  47.188  74.293  1.00 -73.248

我做错了什么或者你有什么想法吗?

答案1

首先从文件2中提取你想要的字段:

value="$(awk -F, 'NR==1{print $3;exit}' file2)"

然后将其插入文件 1 的替换代码中:

awk '{$11 = v} 1' v="$value" file1

答案2

由于您想要的值是第一行的第三列file2,因此您可以通过以下方式获得:

$ awk 'NR==1{print $3}' file2
-81.883,

但是,这还包括您可能不想要的逗号。为了避免这种情况,你可以告诉awk使用任何一个空间或者使用标志作为字段分隔符-F

$ awk -F", " 'NR==1{print $3}' file2
-81.883

awk 允许您使用以下选项在命令行设置变量-v

   -v var=val
   --assign var=val
          Assign the value val to the variable var,  before  execution  of
          the  program  begins.  Such variable values are available to the
          BEGIN rule of an AWK program.

因此,您可以运行awk -vfoo="-81.833" {...},这将使该值可用作awk 脚本中的-81.33变量。foo如果你把它与命令替换,您可以将第一个命令的输出awk(您想要的值)作为变量(例如,称为i)传递给第二个脚本,该脚本将第 11 个字段替换为变量 的值i

$ awk -vi="$(awk -F", " 'NR==1{print $3}' file2)" '{$11=i}1;' file1
HETATM 14 H4B FAD B 600 95.544 50.240 71.308 1.00 -81.883 H
HETATM 14 H4B FAD B 600 95.544 50.240 71.308 1.00 -81.883 H

答案3

我不太明白这个问题,但我想无论如何我都会冒险找到一个解决方案。

sed -nse'1!{  :out
              1x
              s/  */&\n/10
              s/^/ /p;t
           }
           x; s/..*//;t out
           g; s/[^ ]* *[^ ]* *//
              s/ .*//;p
           x;    :eat
           $d;n;b eat
'  file1 file2 file3 file4 |
sed '      /^ /!{h;d;}
           s///;N;G
           s/\n[^ ]*\(.*\)\n\(.*\)/\2\1/
'

这可能有用。如果您有一个sed可以处理-s单独的输入文件流的文件,那么应该交替选择仅从文件一中选择所需的字段和仅为整个文件写入该字段,或者为下一个输入文件标记并准备每个输出行所以第二个sed可以替换有问题的字段。

基本上它适用于文件对 - 从每两个读取文件中的第一个开始,它将仅打印您的源列,然后将该源列编辑到每对的第二个中。

相关内容