一个用于运行不同文件的awk脚本

时间:2016-05-09 10:39:54

标签: bash awk

我写了这个脚本: looking.awk ,用于搜索文件中的特定数据:

 {if ($0 ~ "NEIGHBORS OF THE NON-EQUIVALENT ATOMS") {FLAG=1}};
 # If the current line of the file begins with that string, we asign it a FLAG=1

    {if (FLAG==1)
            {if ($0 ~ $1==1 && $2=="CA" && $6==14 && $7=="O"){LINE=$0;
            exit}
            }
    };
    # Here I am searching for "1 CA" on each line

 END{VOL=FILENAME;
 # The filename is: "c_FROM_V_273_008245_50_neighbours_SYMREMO.out"
 # My intention is to end up with a new file with 2 columns:
 # "volume" and "distance". 
 # Notice that the filename contains the volume: 273.008245

 gsub("^.*_V_","",VOL);
 gsub("_",".",VOL);
 gsub(".50.neighbours.SYMREMO.out"," ",VOL);
 # Some substitutions to make "c_FROM_V_273_008245_50_neighbours_SYMREMO.out" 
 # to be "273.008245"

 # Up to now the output of running: 
 # search_for_distance.awk -f c_FROM_V_273_008245_50_neighbours_SYMREMO.out
 # is the following:

 # 273.008245     1 CA   1     2.4055     4.5458    7 O    0 0 0

 # So, I need to take LINE and only extract column "4".
 # This is done by a "split" command:

 {split(LINE,array," ")}   

 print VOL,array[4]}

该脚本位于当前文件夹.

我有几个文件夹和文件,我想在其中运行此脚本。

这些是 路径

 .../CVOLOPTs_and_f9_for_labels_V_247_803181/c_V_247_803181_50_neighbours_SYMREMO.out

 .../CVOLOPTs_and_f9_for_labels_V_250_532893/c_V_247_803181_50_neighbours_SYMREMO.out

 .
 .
 .

我正在运行脚本:

 awk -f looking.awk ../CVOLOPTs*_V*/calcite_IIIb*V*50_n*_SYMREMO.out > ./d_Ca-1_O_7/data.dat

但是在生成的data.dat中,只有.../CVOLOPTs_and_f9_for_labels_V_247_803181/c_V_247_803181_50_neighbours_SYMREMO.out文件上的脚本结果

如何运行脚本以便查看 路径 中的所有.out个文件?

非常感谢您的帮助

2 个答案:

答案 0 :(得分:2)

可以预见,

exit会导致Awk退出;所以你在CA的第一场比赛后停止处理。

我猜你也许正在寻找nextfile,正如你猜测的那样,它会跳到输入文件列表中的下一个文件。 (请注意,这是一种相对较新的语言添加;如果您使用的是旧版Awk,可能会升级,或者切换到GNU Awk。)

当然,END仅在输入结束时发生;我猜测当前END块中的内容应该发生在nextfile之前,而不是每个输入文件生成一个结果。

切线,您的脚本非常单一。正则表达式匹配的默认范围是$0,所以看起来像

awk '{ if ($0 ~ "moo") ...}'

应该简单地写成

awk '/moo/ { ... }'

此外,如果你所关心的只是$4 LINE,只需替换

LINE=$0

FIELD=$4

避免必须将行拆分回END块中的数组,只是为了提取第四个字段。

你在if ($0 ~ $1==1)中也有一个奇怪的语法错误,我认为不是你想说的。简短测试表明,这会评估$1==1的真值,然后将输入行与此比较的结果(真值为0或1)进行比较。我猜你错误地离开了$0 ~

总结,并注意到我们在这里猜测一个很好的协议,你正在寻找的脚本可能是这样的

awk '/NEIGHBORS OF THE NON-EQUIVALENT ATOMS/ {FLAG=1}
  FLAG==1 && $1==1 && $2=="CA" && $6==14 && $7=="O" {
      VOL=FILENAME;
      gsub("^.*_V_","",VOL); gsub("_",".",VOL);  gsub(".50.neighbours.SYMREMO.out"," ",VOL);
      print VOL, $4;
      nextfile }' list of file names here ...

答案 1 :(得分:1)

  

如何运行脚本以便查看所有.out文件   在那些路径中?

find /base/directory/to/search -type f -name "*.out" -exec awk -f /path/to/looking.awk {} >>/path/to/d_Ca-1_O_7/data.dat \;

这里发生了什么?

  1. 我们将/base/directory/to/search设置为要搜索的基本目录。
  2. 我们要求findtype指令查找文件。
  3. 我们希望查找以.out结尾的所有文件,因此我们将名称设置为*.out*这里是一张外卡,它将扩展到所有可能的输出,我们使用我们在1和1中已经提到的标准进行过滤。 2。
  4. -exec用于在过滤后的输出上应用命令。这只是一个帮助您处理find输出的管道。但与此同时,它与普通管道(|)的不同之处在于,find -say -print0应用的格式由exec保留。格式化是在我们处理非标准文件的情况下完成的,例如,带有换行符或特殊字符的文件。我们使用{}将格式化的字符串传递给命令。
  5. 我们执行awk内容并将结果附加到dat文件。