在特定行之后读取表格并使用 awk 计算出现次数

Ray*_*azi 5 command-line bash awk text-processing

我在一个大日志文件的某处有一个表,看起来像这个例子:

----------------------------
CARTESIAN COORDINATES (A.U.)
----------------------------
  NO LB      ZA    FRAG    MASS        X           Y           Z
   0 C     6.0000    0    12.011         -8.817666638854597         -4.911814574090662         58.264165798697491
   1 C     6.0000    0    12.011         -7.879568488830738         -4.388761616508626         55.950914108733443
   2 C     6.0000    0    12.011         -7.790669273242299         -4.339145245237274         60.527363919786708
   3 C     6.0000    0    12.011         -7.070247938157430         -3.937287748509576         62.694740665963295
   4 C     6.0000    0    12.011         -7.244178391763230         -4.034368638160922         53.748929835486599
   5 H     1.0000    0     1.008         -6.427462410780078         -3.581016558829315         64.562423911622218
   6 H     1.0000    0     1.008         -6.674286700050606         -3.718319003596096         51.850593400164620

--------------------------------
INTERNAL COORDINATES (ANGSTROEM)
--------------------------------
Run Code Online (Sandbox Code Playgroud)

我想告诉awkfindCARTESIAN COORDINATES (A.U.)然后 findNO LB然后开始读取每行中的第二个变量,直到它到达-----.

所以,我会阅读所有的(碳元素(C)氧气(O)氢(H))CH年代和......然后我得到了多少CH的。

我已经并且我可以C5H2在这种情况下创建一个变量,它最终可能是类似的东西C3OH4,有什么想法吗?

awk '
/CARTESIAN COORDINATES (A.U.)/ {fcart=1}
fcart &&
/  NO LB/ {scart=1}


/---------------------------/{exit}
' OFS="\t" "$FILENAME"
Run Code Online (Sandbox Code Playgroud)

cha*_*aos 6

使用这个awk

awk '/CARTESIAN COORDINATES \(A.U.\)/{a=1;next} a==1&&/NO LB/{b=1;next} $0==""{exit}
a==1&&b==1{c[$2]++} END{for(i in c){printf "%s%s", i,c[i]}}' file
Run Code Online (Sandbox Code Playgroud)
  • /CARTESIAN COORDINATES \(A.U.\)/{a=1;next}: 该块搜索CARTESIAN COORDINATES (A.U.)然后将变量设置a1next表示跳转到下一行并从该行重新开始处理。
  • a==1&&/NO LB/{b=1;next}检查是否a1以及是否NO LB在行中的某处找到第二个字符串。它设置变量b,然后加载next行。
  • $0==""{exit}: 然后,如果该行为空,则退出处理(它跳转到END{}块)。
  • a==1&&b==1{c[$2]++}:如果找到两个匹配项(a并且b相等1),则增加一个c用索引$2(字段 2)调用的数组。这将计算第二个字段中每个值的出现次数。
  • END{...}:这将在文件处理完成时运行(数组已填充)。
    • for(i in c) 遍历数组中的每个元素...
    • printf "%s%s", i,c[i]: ... 并打印索引和值。

输出(使用您的示例文件):

C5H2
Run Code Online (Sandbox Code Playgroud)

  • @AB ^^ 今天我在 awk 中思考:`awk 'BEGIN{stand_up("very early")} {work("hard");} END{print "need sleep"; 睡觉”); 退出}'我` (2认同)