Bash 用于将多个文件形成单个文件的循环中的AWK

Bash 用于将多个文件形成单个文件的循环中的AWK,bash,awk,sed,Bash,Awk,Sed,我有以下文件名为ABCD.vasp: # A B C D 1.000000 13.85640621 0.00000000 0.00000000 4.61880236 13.06394496 0.00000000 0.00000000 0.00000000 45.25483322 A B C D 32 32 32 32 Selective dynam

我有以下文件名为
ABCD.vasp

# A B C D
1.000000
     13.85640621        0.00000000        0.00000000
      4.61880236       13.06394496        0.00000000
      0.00000000        0.00000000       45.25483322
A B C D
   32      32      32      32
Selective dynamics
Direct
      0.00000000        0.00000000        0.00000000 F F F
      0.00000000        0.00000000        0.12500000 F F T
      0.00000000        0.00000000        0.25000000 F F T
      0.00000000        0.00000000        0.37500000 F F T
      0.50000000        0.00000000        0.00000000 F F F
      0.50000000        0.00000000        0.12500000 F F T
      0.50000000        0.00000000        0.25000000 F F T
      0.50000000        0.00000000        0.37500000 F F T
      0.12500000        0.37500000        0.06250000 F F T
      0.12500000        0.37500000        0.18750000 F F T
      0.12500000        0.37500000        0.31250000 F F T  
我要对上述文件执行的操作:

  • 我想将第一行
    9
    复制到名为
    test.vasp
  • 行号
    10
    之后,如果第三列
    >=0.25
    ,则第一列应增加
    0.025
    ,整行应追加到
    test1。vasp
  • 行号
    10
    以后,如果第三列是
    $outputfile
    完成
    

    请在
    awk
    sed

    中建议解决方案不要多次调用awk,只需为awk中的每一行写入多个输出文件,如下所示:

    {
        c=0
        for (i=0.025; i<=0.25; i+=0.025) {
            print ...whatever... >> ("test" (++c) ".vasp")
        }
    }
    
    {
    c=0
    对于(i=0.025;i>(“测试”(++c)”.vasp)
    }
    }
    
    对于数字部分,您可以执行以下操作

    $ awk 'NR>9{for(i=1;i<=10;i++)
                  {f="test" i ".vasp";
                   if($3>=0.25) $1=sprintf("%.8f",$1+0.25)
                   print > f}}' file
    
    $awk'NR>9{for(i=1;i=0.25)$1=sprintf(“%.8f”,$1+0.25)
    打印>f}}'文件
    
    将给予

    $ head *.vasp | column -t
    
    ==>         test1.vasp   <==
    0.00000000  0.00000000   0.00000000  F  F  F
    0.00000000  0.00000000   0.12500000  F  F  T
    0.25000000  0.00000000   0.25000000  F  F  T
    0.25000000  0.00000000   0.37500000  F  F  T
    0.50000000  0.00000000   0.00000000  F  F  F
    0.50000000  0.00000000   0.12500000  F  F  T
    0.75000000  0.00000000   0.25000000  F  F  T
    0.75000000  0.00000000   0.37500000  F  F  T
    0.12500000  0.37500000   0.06250000  F  F  T
    0.12500000  0.37500000   0.18750000  F  F  T
    ==>         test10.vasp  <==
    0.00000000  0.00000000   0.00000000  F  F  F
    0.00000000  0.00000000   0.12500000  F  F  T
    2.50000000  0.00000000   0.25000000  F  F  T
    2.50000000  0.00000000   0.37500000  F  F  T
    0.50000000  0.00000000   0.00000000  F  F  F
    0.50000000  0.00000000   0.12500000  F  F  T
    3.00000000  0.00000000   0.25000000  F  F  T
    3.00000000  0.00000000   0.37500000  F  F  T
    0.12500000  0.37500000   0.06250000  F  F  T
    0.12500000  0.37500000   0.18750000  F  F  T
    ==>         test2.vasp   <==
    0.00000000  0.00000000   0.00000000  F  F  F
    0.00000000  0.00000000   0.12500000  F  F  T
    0.50000000  0.00000000   0.25000000  F  F  T
    0.50000000  0.00000000   0.37500000  F  F  T
    0.50000000  0.00000000   0.00000000  F  F  F
    0.50000000  0.00000000   0.12500000  F  F  T
    1.00000000  0.00000000   0.25000000  F  F  T
    1.00000000  0.00000000   0.37500000  F  F  T
    0.12500000  0.37500000   0.06250000  F  F  T
    0.12500000  0.37500000   0.18750000  F  F  T
    ==>         test3.vasp   <==
    0.00000000  0.00000000   0.00000000  F  F  F
    0.00000000  0.00000000   0.12500000  F  F  T
    0.75000000  0.00000000   0.25000000  F  F  T
    0.75000000  0.00000000   0.37500000  F  F  T
    0.50000000  0.00000000   0.00000000  F  F  F
    0.50000000  0.00000000   0.12500000  F  F  T
    1.25000000  0.00000000   0.25000000  F  F  T
    1.25000000  0.00000000   0.37500000  F  F  T
    0.12500000  0.37500000   0.06250000  F  F  T
    0.12500000  0.37500000   0.18750000  F  F  T
    
    $head*.vasp |列-t
    
    ==>test1.vasp test10.vasp test2.vasp test3.vasp您可以使用此
    awk
    脚本

    cat incr.awk
    
    NR <= 9 {
       s = s $0 ORS
       next
    }
    {
       r[++n] = $0
    }
    END {
       for (i=1; i<=10; i++) {
          fn = "test" i ".vasp"
          printf "%s", s > fn
          for (k=1; k<=n; ++k) {
             split(r[k], a)
             if (a[3] >= 0.25) {
                sub(/[^\t]+/, sprintf("%.8f", a[1] + .025), r[k])
             }
             print r[k] > fn
          }
          close(fn)
       }
    }
    

    根据对我先前问题的回答:

    这对我很有用:

    for ((i=1;i<=10;i++));do
       outputfile=test"$i".vasp
       awk -v I=$(( i * 0.025 )) 'NR > 9 && $3+0 >= 0.25 {
       p = $1; p +=I; sub(/[^ \t]+/, sprintf("%.8f", p)) } 1' $inputfile > $outputfile
    done
    
    ((i=1;i$outputfile)的
    
    完成
    
    据我所知,你的问题都在文件“test.vasp”中。那么你想如何生成多个文件……所有这些文件之间的区别是什么?@kvantour我已经更新了这个问题。你的意思是增量在0.025 0.05 0.075之间变化还是限制?@kvantour增量应该在0.025.Fo之间r test1.vasp文件,增量为1*0.025=0.025,对于test2.vasp,增量为2*0.025=0.050…对于test10.vasp,增量为10*0.025=0.25,for循环内部分数在BASH中不起作用,因为BASH只能处理整数。主要问题是如何管理代码的打印部分。这是一个Awk脚本,您可以在其中使用分数everywhere.将其存储在一个文件中,并使用
    awk-f file
    @Sufyan运行它您似乎对在awk之外添加一个shell循环的想法很感兴趣-不要这样做。只需给awk打一次电话,然后使用我显示的修改为循环的现有awk代码。哦!我完全忘记了awk脚本。谢谢,@tripleei使用了您之前的答案并对其进行了修改一点。检查我的答案是否有效。这不是一个有效的解决方案,因为它调用了
    awk
    10次。请检查我的答案以在一条awk命令中执行此操作。您有3个答案不执行此操作,并且有多条注释建议您不要执行此操作。您可能需要重新考虑执行此操作。我尝试了此操作,但它没有保留第1-8行到测试文件。是的,“对于数字部分”仅在输出中可以看到。在您的帖子中,您写道“我想将前9行复制到一个名为test.vasp的新文件中”,所以我认为数据部分不包括这些行?如果不包括,则添加起来很简单。格式也不保留。
    awk -f incr.awk file
    
    for ((i=1;i<=10;i++));do
       outputfile=test"$i".vasp
       awk -v I=$(( i * 0.025 )) 'NR > 9 && $3+0 >= 0.25 {
       p = $1; p +=I; sub(/[^ \t]+/, sprintf("%.8f", p)) } 1' $inputfile > $outputfile
    done