Awk 如何将.xvg文件转换为.xyz文件(将一行拆分为多行)?

Awk 如何将.xvg文件转换为.xyz文件(将一行拆分为多行)?,awk,Awk,我想转换一个文件vel.xvg 0 0.303345 0.0430715 1.46423 0.354741 0.124701 1.49059 0.320466 1.5482 1.53037 0.0892707 1.07608 0.545043 0.000847689 1.07834 0.498392 0.1477

我想转换一个文件
vel.xvg

0      0.303345        0.0430715       1.46423      0.354741        0.124701         1.49059        0.320466        1.5482      1.53037     0.0892707       1.07608     0.545043        0.000847689     1.07834     0.498392        0.1477      1.14895     0.509314
1      0.301998        0.0438025       1.4651       0.356303        0.122887         1.49332        0.319646        1.54791     1.52995     0.0896649       1.07605     0.54495        0.000783547      1.07822     0.499174        0.14217      1.1499    0.50264
2      0.300672        0.0444949       1.46599      0.358753        0.120221         1.49586        0.31959         1.54831     1.53015     0.0900906       1.07607     0.544848       0.000537069      1.07801     0.500391        0.136618     1.15043     0.49682
要归档
vel.xyz

6
i =  0
O   0.303345  0.0430715  1.46423
H   0.354741  0.124701  1.49059
H   0.320466  1.5482  1.53037
O   0.0892707  1.07608  0.545043
H   0.000847689  1.07834  0.498392
H   0.1477  1.14895  0.509314
6
i =  1
O   0.301998  0.0438025  1.4651
H   0.356303  0.122887  1.49332
H   0.319646  1.54791  1.52995
O   0.0896649  1.07605  0.54495
H   0.000783547  1.07822  0.499174
H   0.14217  1.1499  0.50264
6
i =  2
O   0.300672  0.0444949  1.46599
H   0.358753  0.120221  1.49586
H   0.31959  1.54831  1.53015
O   0.0900906  1.07607  0.544848
H   0.000537069  1.07801  0.500391
H   0.136618  1.15043  0.49682
首先,我使用了命令

awk -v f=2  '{print "6","\n","i = ",$1}{for(i=f;i<=NF;i++){printf("%s%s ",$i,(i-1)%3?",":"\n")}}' vel.xvg > tmp
然后,我为一些带有代码的行添加标签
O
H

awk -v t=8  '{if((NR%t>2)&&(NR%t)%3==0) print "O ",$0; else if(((NR%t>2)&& (NR%t)%3==1) ||((NR%t>2)&&(NR%t)%3==2)) print "H ",$0; else{print}}' tmp | awk -v t=8 '{if(NR%t==0) print "H ",$0; else{print}}' > vel.xyz
并获得输出

6
i =  0
O  0.303345, 0.0430715, 1.46423
H   0.354741, 0.124701, 1.49059
H   0.320466, 1.5482, 1.53037
O   0.0892707, 1.07608, 0.545043
H   0.000847689, 1.07834, 0.498392
H   0.1477, 1.14895, 0.509314
6
i =  1
O  0.301998, 0.0438025, 1.4651
H   0.356303, 0.122887, 1.49332
H   0.319646, 1.54791, 1.52995
O   0.0896649, 1.07605, 0.54495
H   0.000783547, 1.07822, 0.499174
H   0.14217, 1.1499, 0.50264 
6
i =  2 
O  0.300672, 0.0444949, 1.46599
H   0.358753, 0.120221, 1.49586
H   0.31959, 1.54831, 1.53015
O   0.0900906, 1.07607, 0.544848
H   0.000537069, 1.07801, 0.500391
H   0.136618, 1.15043, 0.49682

有人能提出一个更好更干净的方法来解决这个问题吗

这应该是不言自明的

awk '{print 6"\ni = "$1; 
      for(i=2;i<=NF;i+=3) 
          print (i%9==2?"O":"H")"\t",$i,$(i+1),$(i+2)}'
awk'{print 6'\ni=“$1;

对于(i=2;i这就是你想要的吗

$ cat tst.awk
BEGIN { numCols=3 }
{
    numRows = (NF-1) / numCols
    print numRows ORS "i =", $1
    fldNr = 1
    for (rowNr=1;rowNr<=numRows;rowNr++) {
        printf (rowNr%numCols==1?"O":"H")
        for (colNr=1;colNr<=numCols;colNr++) {
            printf "%s%s", OFS, $(++fldNr)
        }
        print ""
    }
}

如果((NR%365)-2)%3==1)
,你的
中缺少
。正如@loolo所说。如果你在编辑器中(宣传和)使用语法着色;^)编写脚本,这对你来说是显而易见的。测试后,我发现以下代码可以解决这个问题:
awk-vt=365'{if((NR%t>2)&(NR%t)%3==0)printf((2)和(NR%t%t)3=t=t=t=t=t=t=t=t=t=t=t=t=3=1)(1)1)作为(2)和(NR%t%t>2)和(3%t%t>2)和(2%t%t>2)和(NR%t%t%t>2)和(3%t%t%t%t%t%t>2)和(2)和(3%t%t%t%t%t%t%t%t%t%t%t>2)3=3=3=3=3=3=2)s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%代码>打印“H”,$0
)但是您认为您需要在其他(
printf(
printf(“%s%s%s%s”,“H”,“1,$2,$3,“\n”)
vs
print“H”、$1,$2,$3
)中使用
printf
)。脚本可以编写得简单得多,但如果没有可测试的样本输入和预期的输出(例如,去掉所有
,并确保它们特别匹配),我们无法帮助您与其只是希望有更好的方法,不如编辑您的问题,使其具有可测试的示例输入和输出,并清楚地解释输入字段如何映射到输出字段(不要假设我们知道或关心“.xvg”或任何其他格式的含义-对我们来说,这些都只是字段的行和列)你几乎肯定会得到一个更好的方法。当记录远大于6时,它会起作用!@Ed Morton。我使用
{print 6 or“I=”,$1 fldNr=1(j=1;jYes!!@Ed Morton那太好了!谢谢!我修改了它,使用变量numRows和numCols,您可以设置/计算所需的行数和列数。's答案准确而漂亮。谢谢。
$ cat tst.awk
BEGIN { numCols=3 }
{
    numRows = (NF-1) / numCols
    print numRows ORS "i =", $1
    fldNr = 1
    for (rowNr=1;rowNr<=numRows;rowNr++) {
        printf (rowNr%numCols==1?"O":"H")
        for (colNr=1;colNr<=numCols;colNr++) {
            printf "%s%s", OFS, $(++fldNr)
        }
        print ""
    }
}
$ awk -f tst.awk file
6
i = 0
O 0.303345 0.0430715 1.46423
H 0.354741 0.124701 1.49059
H 0.320466 1.5482 1.53037
O 0.0892707 1.07608 0.545043
H 0.000847689 1.07834 0.498392
H 0.1477 1.14895 0.509314
6
i = 1
O 0.301998 0.0438025 1.4651
H 0.356303 0.122887 1.49332
H 0.319646 1.54791 1.52995
O 0.0896649 1.07605 0.54495
H 0.000783547 1.07822 0.499174
H 0.14217 1.1499 0.50264
6
i = 2
O 0.300672 0.0444949 1.46599
H 0.358753 0.120221 1.49586
H 0.31959 1.54831 1.53015
O 0.0900906 1.07607 0.544848
H 0.000537069 1.07801 0.500391
H 0.136618 1.15043 0.49682