Bash 对列中的字符进行计数和索引

Bash 对列中的字符进行计数和索引,bash,indexing,awk,grep,Bash,Indexing,Awk,Grep,我有一个文件system.xyz,其中有几列: 43 Built with Packmol O 37.536208 36.873149 9.514500 C 37.768292 35.784076 10.014380 N 37.749829 34.667899 9.235406 C 38.014779

我有一个文件
system.xyz
,其中有几列:

          43
  Built with Packmol
  O           37.536208       36.873149        9.514500
  C           37.768292       35.784076       10.014380
  N           37.749829       34.667899        9.235406
  C           38.014779       33.336113        9.750827
  C           37.921777       32.283049        8.635104
  C           38.203826       30.885654        9.187454

并需要将其更改为:

@atom:o1 @mol: $atom:O 0 37.536208 36.873149 9.514500
@atom:c1 @mol: $atom:C 0 37.768292 35.784076 10.014380
@atom:n1 @mol: $atom:N 0 37.749829 34.667899 9.235406
@atom:c2 @mol: $atom:C 0 38.014779 33.336113 9.750827
@atom:c3 @mol: $atom:C 0 37.921777 32.283049 8.635104
@atom:c4 @mol: $atom:C 0 38.203826 30.885654 9.187454
我已经设法使用了这个
grep-A43 builded system.xyz | awk'{print“@atom:$tolower($1),“@mol:$atom:$1,$0,$2,$3,$4}”

@atom:built @mol: $atom:Built 0 with Packmol 
@atom:o @mol: $atom:O 0 37.536208 36.873149 9.514500
@atom:c @mol: $atom:C 0 37.768292 35.784076 10.014380
@atom:n @mol: $atom:N 0 37.749829 34.667899 9.235406
@atom:c @mol: $atom:C 0 38.014779 33.336113 9.750827
@atom:c @mol: $atom:C 0 37.921777 32.283049 8.635104
@atom:c @mol: $atom:C 0 38.203826 30.885654 9.187454
但是我必须手动输入第一列中每个字符的索引。有没有办法对第一列中的字符进行计数和索引?

试试以下方法:

awk'
开始{fmt=“@atom:%s%d@mol:$atom:%s 0”}
{$1=sprintf(fmt,tolower($1),++count[tolower($1)],$1)}
1.
'

如果你认为
grep-A43-build
的意思是“43后匹配构建”,那是不正确的,它的意思是“匹配构建并包含后面的43行”。如果不是这样的话,如果您能解释一下为什么需要
-A43
,那就太好了,我看不到您的问题中提到了43行。是的,文件开头的43实际上告诉我在
构建之后的行数
,因此最好也自动读取43而不是手动写入
-A43
在43行之后还有其他行不应该处理吗?如果是,是否有任何类型的分隔符,或者后面的行是否有任何不同,例如,新的数字&“Build with Packmol”行?因为如果有其他方法可以找到你应该阅读的内容的结尾,你可能不需要阅读这个数字。也就是说提取数字也不难,例如,您可以使用
grep-B1 builded | grep-Eo'[0-9]+'
从未想过要做~
fmt=“%s”;printf fmt,var
。谢谢,太棒了!谢谢你!编辑:对于那些致力于将xyz文件转换为MOLTTemplate文件的人,我把符号搞错了。这就像一个符咒:
cat system.xyz|awk'BEGIN{fmt=“$atom:%s%d$mol:@atom:%s 0”}{$1=sprintf(fmt,tolower($1),++count[tolower($1)],$1'
@Hud不需要这个
cat|awk
,awk可以自己处理文件。使用
awk。。。改为文件
。干杯。最终编辑
awk'BEGIN{fmt=“$atom:%s%d$mol:..@atom:%s 0”}{$1=sprintf(fmt,tolower($1),++count[tolower($1)],$1}system.xyz