Replace 用awk替换列,保留格式
这是文件a.pdb: 这是文件a.xyz: 我想用a.xyz列替换a.pdb的6、7和第8列。一旦被替换,我需要维护a.pdb的制表符/空格/列 我试过:Replace 用awk替换列,保留格式,replace,awk,format,Replace,Awk,Format,这是文件a.pdb: 这是文件a.xyz: 我想用a.xyz列替换a.pdb的6、7和第8列。一旦被替换,我需要维护a.pdb的制表符/空格/列 我试过: awk 'NR==FNR {fld1[NR]=$1; fld2[NR]=$2; fld3[NR]=$3; next} {$6=fld1[FNR]; $7=fld2[FNR]; $8=fld3[FNR]}1' a.xyz a.pdb 但是它没有保留格式。不是通用的解决方案,但在这种特殊情况下,这可能适用于: awk 'NR==FNR{for
awk 'NR==FNR {fld1[NR]=$1; fld2[NR]=$2; fld3[NR]=$3; next} {$6=fld1[FNR]; $7=fld2[FNR]; $8=fld3[FNR]}1' a.xyz a.pdb
但是它没有保留格式。不是通用的解决方案,但在这种特殊情况下,这可能适用于:
awk 'NR==FNR{for(i=6; i<=8; i++) A[FNR,i]=$(i-5); next} {for(i=6; i<=8; i++) sub($i,A[FNR,i])}1' file2 file1
-在OP的原始解决方案中更改它:
awk 'NR==FNR {fld1[NR]=$1; fld2[NR]=$2; fld3[NR]=$3; next} {sub($6,fld1[FNR]); sub($7,fld2[FNR]); sub($8,fld3[FNR])}1' file file1
与前两个建议具有相同的限制
因此,1、2和4使用sub替换,这不是防水的解决方案,因为早期的字段可能会干扰,并且它使用正则表达式而不是字符串,因此正则表达式点恰好与实际点匹配,但使用此特定输入,它可能会平移
3号可能是一种更简单的方法
-编辑-
我认为在给定的输入条件下,这会起作用:
awk 'NR==FNR{A[FNR]=$1 " " $2 " " $3; next} {print substr($0,1,p) A[FNR] substr($0,p+length(A[FNR]))}' p=32 file2 file1
但我认为需要printf或sprint格式这样的东西才能使它变得简单。
所以,也许是这样的:
awk 'NR==FNR{A[FNR]=sprintf("%7.3f %7.3f %8.4f", $1, $2, $3); next} {print substr($0,1,p) A[FNR] substr($0,p+length(A[FNR]))}' p=31 file2 file1
或者不在一行上:
awk '
NR==FNR {
A[FNR]=sprintf("%7.3f %7.3f %8.4f", $1, $2, $3)
next
}
{
print substr($0,1,p) A[FNR] substr($0,p+length(A[FNR]))
}
' p=31 file2 file1
不是一个通用的解决方案,但在这种特殊情况下,这可能适用于:
awk 'NR==FNR{for(i=6; i<=8; i++) A[FNR,i]=$(i-5); next} {for(i=6; i<=8; i++) sub($i,A[FNR,i])}1' file2 file1
-在OP的原始解决方案中更改它:
awk 'NR==FNR {fld1[NR]=$1; fld2[NR]=$2; fld3[NR]=$3; next} {sub($6,fld1[FNR]); sub($7,fld2[FNR]); sub($8,fld3[FNR])}1' file file1
与前两个建议具有相同的限制
因此,1、2和4使用sub替换,这不是防水的解决方案,因为早期的字段可能会干扰,并且它使用正则表达式而不是字符串,因此正则表达式点恰好与实际点匹配,但使用此特定输入,它可能会平移
3号可能是一种更简单的方法
-编辑-
我认为在给定的输入条件下,这会起作用:
awk 'NR==FNR{A[FNR]=$1 " " $2 " " $3; next} {print substr($0,1,p) A[FNR] substr($0,p+length(A[FNR]))}' p=32 file2 file1
但我认为需要printf或sprint格式这样的东西才能使它变得简单。
所以,也许是这样的:
awk 'NR==FNR{A[FNR]=sprintf("%7.3f %7.3f %8.4f", $1, $2, $3); next} {print substr($0,1,p) A[FNR] substr($0,p+length(A[FNR]))}' p=31 file2 file1
或者不在一行上:
awk '
NR==FNR {
A[FNR]=sprintf("%7.3f %7.3f %8.4f", $1, $2, $3)
next
}
{
print substr($0,1,p) A[FNR] substr($0,p+length(A[FNR]))
}
' p=31 file2 file1
你可以试试这个
paste -d' ' test4 test5 |awk '{print $1,$2,$3,$4,$5,$12,$13,$14,$9,$10,$11}'
你可以试试这个
paste -d' ' test4 test5 |awk '{print $1,$2,$3,$4,$5,$12,$13,$14,$9,$10,$11}'
这正是GNU awk中split的第四个arg的发明目的:
gawk '
NR==FNR { pdb[NR]=$0; next }
{
split(pdb[FNR],flds,FS,seps)
flds[6]=$1
flds[7]=$2
flds[8]=$3
for (i=1;i in flds;i++)
printf "%s%s", flds[i], seps[i]
print ""
}
' a.pdb a.xyz
ATOM 1 N ARG 1 16.388 -5.760 -23.332 1.00 0.00 N
ATOM 2 H1 ARG 1 17.226 -5.608 -23.768 1.00 0.00 H
ATOM 3 H2 ARG 1 15.760 -5.238 -23.831 1.00 0.00 H
ATOM 4 H3 ARG 1 17.921 -5.926 -26.697 1.00 0.00 H
这正是GNU awk中split的第四个arg的发明目的:
gawk '
NR==FNR { pdb[NR]=$0; next }
{
split(pdb[FNR],flds,FS,seps)
flds[6]=$1
flds[7]=$2
flds[8]=$3
for (i=1;i in flds;i++)
printf "%s%s", flds[i], seps[i]
print ""
}
' a.pdb a.xyz
ATOM 1 N ARG 1 16.388 -5.760 -23.332 1.00 0.00 N
ATOM 2 H1 ARG 1 17.226 -5.608 -23.768 1.00 0.00 H
ATOM 3 H2 ARG 1 15.760 -5.238 -23.831 1.00 0.00 H
ATOM 4 H3 ARG 1 17.921 -5.926 -26.697 1.00 0.00 H
替换算法是什么?一个文件的第一行与另一个文件的第一行内容?行号匹配@fedorquiWell我猜a.pdb是制表符分隔的,而a.xyz是空格分隔的。如果将这两个选项都设置为tab sep呢?我尝试使用cat a.xyz | column-t选项,但在awk替换后,a.pdb的格式变松了。它不会保持列号对齐。是否使用BEGIN{FS=OFS=\t}解释FS和OFS?祝你好运,替换算法是什么?一个文件的第一行与另一个文件的第一行内容?行号匹配@fedorquiWell我猜a.pdb是制表符分隔的,而a.xyz是空格分隔的。如果将这两个选项都设置为tab sep呢?我尝试使用cat a.xyz | column-t选项,但在awk替换后,a.pdb的格式变松了。它不会保持列号对齐。是否使用BEGIN{FS=OFS=\t}解释FS和OFS?祝你好运。注意OPs语法很好,他只是要求保留格式。@fedorqui,好的观点,我在其他建议中添加了一个改编。除了第6-8列中的一个小移位外,它是有效的。a.pdb中的第6-8列左对齐。小数点应该出现在第35、43和51列中。注意OPs语法很好,他只是要求保留格式。@fedorqui,好的,我在其他建议中添加了一个修改。除了在第6-8列中有一个小的变化外,它是有效的。a.pdb中的第6-8列左对齐。小数点应该出现在第35、43和51列中。做得很好。我想利用我的投票来回答一个问题:。在for循环中,您选择在flds中使用i,而不是捕获分割函数返回值,并且无论采用哪种方式都没有什么大不了的,它只是少了一个全局变量,您不必担心填充,也不必担心与脚本中其他地方同名的变量发生冲突。显然,在这么小的脚本中没有问题。注意,这种方法只有在数组索引中没有洞的情况下才有效。明白了!谢谢你的解释+1正式给予!顺便说一句,每个人的桌子上都需要一本awk食谱!眨眼眨眼是的,我已经考虑过了。类似于Chris Johnson的Bash脚本编写方法,但适用于awk。总有一天…+1用于gawk的漂亮功能,Ed。但是小数点不在第35、43和51列。做得很好。我想利用我的投票来回答一个问题:。在for循环中,您选择在flds中使用i,而不是捕获分割函数返回值,并且无论采用哪种方式都没有什么大不了的,它只是少了一个全局变量,您不必担心填充,也不必担心与脚本中其他地方同名的变量发生冲突。显然,在这么小的脚本中没有问题。注意,这种方法只有在数组索引中没有洞的情况下才有效。明白了!谢谢你的解释+1正式给予!顺便说一句,每个人的桌子上都需要一本awk食谱!眨眼眨眼是的,我已经考虑过了。类似于Chris Johnson的Bash脚本编写方法,但是
为了awk。总有一天…+1用于gawk的nice功能,Ed.但小数点不在第35、43和51列中。