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))C的H年代和......然后我得到了多少C的H的。
我已经并且我可以C5H2在这种情况下创建一个变量,它最终可能是类似的东西C3OH4,有什么想法吗?
awk '
/CARTESIAN COORDINATES (A.U.)/ {fcart=1}
fcart &&
/ NO LB/ {scart=1}
/---------------------------/{exit}
' OFS="\t" "$FILENAME"
Run Code Online (Sandbox Code Playgroud)
使用这个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.)然后将变量设置a为1,next表示跳转到下一行并从该行重新开始处理。a==1&&/NO LB/{b=1;next}检查是否a是1以及是否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)