2014-02-17 76 views
-2

我有一个文本文件(前两行的字间距):编辑文本列

  1   2   3   4   5   6   7   8 
123456789
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 
123456789
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)。因此,我想用(“N001”)替换文件1中的字符13-16(“N1”),并将文件的其余部分保留在原始间距中。

+1

不错。你到目前为止尝试了什么?你卡在哪里? – fedorqui

回答

2

你不需要10行样本输入来演示e问题或解决方案:

$ 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作为第三个字段的数字部分。它似乎随着你的行号顺序递增。使用NR可能是一种选择。如果这两者都不是您想要的,请发布一些更具代表性的示例输入/输出。

另外,请注意,涉及分配给字段(例如$3=...)的任何解决方案都会导致awk使用OFS的值作为字段分隔符重新编译该行,因此会更改您的间距。

哦,如果字符间距的2条初始线在你的文件确实存在,这是好办法:

$ cat file 
     1   2 
123456789
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 
123456789
ATOM  1 N001 SPINA 3 
ATOM  2 N002 SPINA 3 
ATOM  10 N010 SPINA 3 
+0

这正是我想做的感谢。字符间距的两个最初线只是为了传达问题而不在文件中。 – user3319181

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 
+0

这对编号很有效,但我想保持文件中的初始间距。如果我删除命令的OFS = \\ t部分,则输出现在是空格分隔符,但是我需要保留原始文件中字符之间的空格的确切数量。有没有办法做到这一点。附:如果你有时间,你能通过命令说说我吗?并感谢您的帮助! – user3319181

+1

谢谢Jaypal,@ user3319181:当你发布的问题你没有提到有关字段间距,它是行间距,字段间距不同于行间距,我真的不知道负面投票的原因。谢谢 - 阿克沙 –

+0

我没有意识到我给你一个否定的投票 – user3319181

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 
+0

+1非常好的方法Jaypal辉煌 - 阿克沙 –

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