我想使用 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
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
可以替换有问题的字段。
基本上它适用于文件对 - 从每两个读取文件中的第一个开始,它将仅打印您的源列,然后将该源列编辑到每对的第二个中。