我有一个文本文件(前两行是字符间距):
1 2 3 4 5 6 7 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 ATOM 1 N1 SPINA 3 30.616 29.799 14.979 1.00 20.00 S N ATOM 2 N1 SPINA 3 28.146 28.381 13.950 1.00 20.00 S N ATOM 3 N1 SPINA 3 27.605 28.239 14.037 1.00 20.00 S N ATOM 4 N1 SPINA 3 30.333 29.182 15.464 1.00 20.00 S N ATOM 5 N1 SPINA 3 29.608 29.434 14.333 1.00 20.00 S N ATOM 6 N1 SPINA 3 29.303 29.830 13.317 1.00 20.00 S N ATOM 7 N1 SPINA 3 28.963 31.116 13.472 1.00 20.00 S N ATOM 8 N1 SPINA 3 28.859 28.743 13.828 1.00 20.00 S N ATOM 9 N1 SPINA 3 29.699 30.575 14.564 1.00 20.00 S N ATOM 10 N1 SPINA 3 29.518 29.194 15.301 1.00 20.00 S N
我想编辑它并使它像:
1 2 3 4 5 6 7 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 ATOM 1 N001 SPINA 3 30.616 29.799 14.979 1.00 20.00 S N ATOM 2 N002 SPINA 3 28.146 28.381 13.950 1.00 20.00 S N ATOM 3 N003 SPINA 3 27.605 28.239 14.037 1.00 20.00 S N ATOM 4 N004 SPINA 3 30.333 29.182 15.464 1.00 20.00 S N ATOM 5 N005 SPINA 3 29.608 29.434 14.333 1.00 20.00 S N ATOM 6 N006 SPINA 3 29.303 29.830 13.317 1.00 20.00 S N ATOM 7 N007 SPINA 3 28.963 31.116 13.472 1.00 20.00 S N ATOM 8 N008 SPINA 3 28.859 28.743 13.828 1.00 20.00 S N ATOM 9 N009 SPINA 3 29.699 30.575 14.564 1.00 20.00 S N ATOM 10 N010 SPINA 3 29.518 29.194 15.301 1.00 20.00 S N
每列之间的空格数很重要,原子列表需要达到190(N001-N190)。因此,我想将文件1中的字符13-16(“N1”)替换为(“N001”),并将文件的其余部分保留为原始间距。
答案 0 :(得分:2)
您不需要10行长的样本输入来演示问题或解决方案:
$ cat file
ATOM 1 N1 SPINA 3
ATOM 2 N1 SPINA 3
ATOM 10 N1 SPINA 3
$ awk '{print substr($0,1,12) sprintf("N%03d",$2) substr($0,17)}' file
ATOM 1 N001 SPINA 3
ATOM 2 N002 SPINA 3
ATOM 10 N010 SPINA 3
我假设我们可以使用$ 2作为第3个字段的数字部分。它似乎按行号顺序递增。使用NR可能是另一种选择。如果这些都不是您想要的,请发布更具代表性的样本输入/输出。
另请注意,任何涉及分配给字段的解决方案(例如$3=...
)都会导致awk使用OFS的值作为字段分隔符重新编译该行,因此会更改您的间距。
哦,如果这两个字符间距的初始行确实存在于你的文件中,那就是调整:
$ cat file
1 2
12345678901234567890123456
ATOM 1 N1 SPINA 3
ATOM 2 N1 SPINA 3
ATOM 10 N1 SPINA 3
$ awk 'NR>2{$0 = substr($0,1,12) sprintf("N%03d",$2) substr($0,17)} 1' file
1 2
12345678901234567890123456
ATOM 1 N001 SPINA 3
ATOM 2 N002 SPINA 3
ATOM 10 N010 SPINA 3
答案 1 :(得分:1)
尝试:
$ awk '{$3=substr($3,1,1) sprintf("%03d",$2)}1' OFS=\\t file
注意:OFS将是标签
如果您想在Solaris/SunOS
系统上尝试此操作,请将awk
更改为/usr/xpg4/bin/awk
,/usr/xpg6/bin/awk
或nawk
<强> - 编辑 - 强>
如果你想用行增加
$ awk '{$3=substr($3,1,1) sprintf("%03d",NR)}1' OFS=\\t file
答案 2 :(得分:1)
这是另一种方式:
awk 'sub(/.$/,sprintf("%03d",NR),$3)' OFS='\t' file
<强>输出:强>
$ awk 'sub(/.$/,sprintf("%03d",NR),$3)' OFS='\t' file
ATOM 1 N001 SPINA 3 30.616 29.799 14.979 1.00 20.00 S N
ATOM 2 N002 SPINA 3 28.146 28.381 13.950 1.00 20.00 S N
ATOM 3 N003 SPINA 3 27.605 28.239 14.037 1.00 20.00 S N
ATOM 4 N004 SPINA 3 30.333 29.182 15.464 1.00 20.00 S N
ATOM 5 N005 SPINA 3 29.608 29.434 14.333 1.00 20.00 S N
ATOM 6 N006 SPINA 3 29.303 29.830 13.317 1.00 20.00 S N
ATOM 7 N007 SPINA 3 28.963 31.116 13.472 1.00 20.00 S N
ATOM 8 N008 SPINA 3 28.859 28.743 13.828 1.00 20.00 S N
ATOM 9 N009 SPINA 3 29.699 30.575 14.564 1.00 20.00 S N
ATOM 10 N010 SPINA 3 29.518 29.194 15.301 1.00 20.00 S N
答案 3 :(得分:1)
如果您对使用纯shell解决它感兴趣,请输入以下代码:
while IFS="\n" read -r line
do
n=${line:9:3}
printf "%sN%03d%s\n" "${line:0:12}" $n "${line:16}"
done < file