【问题标题】:Operations on tabular data text file using awk使用 awk 对表格数据文本文件进行操作
【发布时间】:2017-01-28 05:05:42
【问题描述】:

我通过从一组日志文件中提取信息来生成一个长表格文本文件。我想对生成的表格数据进行一些操作,并使用表格数据创建一个新的文本文件。

我的表格数据如下所示

Compound    State       Method      Approach    Energy
C(CCH)2         singlet     CC          Triplet orbs    not converged or error  3-1/C-CCH-2/C-CCH-2-CC-s.out
C(CCH)2         singlet     CC          Triplet orbs    -191.426232325854   3-1/C-CCH-2/C-CCH-2-s.out
C(CCH)2         triplet     CC          Triplet orbs    -191.434509836762   3-1/C-CCH-2/C-CCH-2-t.out
C(NH2)2         triplet     DFT         Triplet orbs    not converged or error  3-1/C-NH2-2/C-NH2-2-t.out
C(NMe2)2        triplet     DFT         Triplet orbs    not converged or error  3-1/C-NMe2-2/C-NMe2-2-t.out
C(SH)2          singlet     CC          Triplet orbs    not converged or error  3-1/C-SH-2/C-SH-2-CC-s.out
C(SH)2          singlet     DFT         Triplet orbs    -835.261598037781   3-1/C-SH-2/C-SH-2-s.out
C(SH)2          triplet     DFT         Triplet orbs    -835.190581480918   3-1/C-SH-2/C-SH-2-t.out
C(SiH3)2        singlet     CC          Triplet orbs    not converged or error  3-1/C-SiH3-2/C-SiH3-2-CC-s.out
C(SiH3)2        singlet     DFT         Triplet orbs    -620.339326760127   3-1/C-SiH3-2/C-SiH3-2-s.out
C(SiH3)2        triplet     DFT         Triplet orbs    -620.379515709604   3-1/C-SiH3-2/C-SiH3-2-t.out
CF2             singlet     CC          Triplet orbs    not converged or error  3-1/CF2/CF2-CC-s.out
CF2             singlet     DFT         Triplet orbs    -237.686609290184   3-1/CF2/CF2-s.out
CF2             triplet     DFT         Triplet orbs    -237.601091999318   3-1/CF2/CF2-t.out
CF2C            singlet     CC          Triplet orbs    not converged or error  3-1/CF2C/CF2C-CC-s.out
CF2C            singlet     DFT         Triplet orbs    -275.668206445318   3-1/CF2C/CF2C-s.out
CF2C            triplet     DFT         Triplet orbs    -275.641632193745   3-1/CF2C/CF2C-t.out
CH2             singlet     CC          Triplet orbs    -39.061384267881    3-1/CH2/CH2-CC-s.out
CH2             singlet     DFT         Triplet orbs    -39.109884610315    3-1/CH2/CH2-s.out
CH2             triplet     DFT         Triplet orbs    -39.129586138474    3-1/CH2/CH2-t.out

生成它的代码如下:

awk '
BEGIN           {print "Compound\tState\t\tMethod\t\tApproach\tEnergy"}'
find . -name '*.out' | while read FILENAME

do

awk '
FNR==1          {if (FILENAME ~ /-/) 
                  { sub("./","", FILENAME);m=split(FILENAME, Ti, "/") 
                             n=split(Ti[m], T, "-")
                             if (length(T[1]) < 2 ) {T[1]=T[1]"("T[2]")"substr(T[3],1,1)}
                             printf("%-15.10s\t%-10s\t%-10s\t%-10s\t",  T[1], substr(T[n],1,1)=="t"?"triplet":"singlet", FILENAME~"-CC"?"CC":"DFT",FILENAME~"3-1"?"Triplet orbs":"NONE");
                             FOUND=0
                 }
                 else
                  {sub("./","", FILENAME);m=split(FILENAME, Ti, "/") 
                             n=split(Ti[m], T, ".")
                             if (length(T[1]) < 2 ) {T[1]=T[1]"("T[2]")"T[3]}
                             printf ("%-15.10s\t%-10s\t%-10s\t%-10s\t", T[1] , "Singlet", "DFT",FILENAME~"3-1"?"Triplet orbs":"NONE");
                             FOUND=0
                }
                }
/HURRAY/        {FOUND=1; 
                }
FOUND &&
/^FINAL.*ERGY/  {print $NF " \t" FILENAME 
                 CONV=1
                }
END             {if (!CONV) print "not converged or error\t" FILENAME 
                };       
' OFS="\t" "$FILENAME"
done 

每当列:Compound、Method 和 Approach 是匹配的能量值时,我想将它们彼此完全减少为 Singlet-Triplet,并一起形成一个新的表格数据。 例如

CF2             singlet     DFT         Triplet orbs    -237.686609290184   3-1/CF2/CF2-s.out
CF2             triplet     DFT         Triplet orbs    -237.601091999318   3-1/CF2/CF2-t.out

组成一行

CF2             DFT         Triplet orbs    0.085517290866  

当然,如果未找到匹配项,则只是一个简单的错误匹配项未找到或数据不可用。 感谢您的帮助。

【问题讨论】:

    标签: awk tabular


    【解决方案1】:

    我没有尝试阅读您的 awk 脚本,但假设您从上面列出的数据开始

    awk -vOFS="\t" -f m.awk data
    

    会生成

    C(CCH)2     CC      Triplet orbs    -0.00827751
    C(SH)2      DFT     Triplet orbs    0.0710166
    C(SiH3)2    DFT     Triplet orbs    -0.0401889
    CF2 DFT     Triplet orbs    0.0855173
    CF2C        DFT     Triplet orbs    0.0265743
    CH2 DFT     Triplet orbs    -0.0197015
    

    这是脚本

     $ cat m.awk
        {
          k = $1 OFS $3 OFS $4
        }
        $2 ~ /singlet/  {
          if ($6 = $6 + 0) {
            if (k in t) {
              print k, $5, t[k] - $6
              t[k] = ""
            } else {
              s[k] = $6
            }
          }
        }
    
        $2 ~ /triplet/  {
          if ($6 = $6 + 0) {
            if (k in s) {
              print k, $5, $6 - s[k]
              s[k] = ""
            } else {
              t[k] = $6
            }
          }
        }
    

    解释:从字段 1,3,4 构造键。当值为数字时,尝试匹配单重态和三重态对。当使用一对时,使使用的值无效。

    我们可以将通用逻辑提取到一个函数中以进一步简化代码

      function pairup(t,s,sign) {
        if ($6 = $6 + 0) {
          if (k in t) {
            print k, $5, sign*(t[k] - $6)
            delete t[k]
          } else {
            s[k] = $6
          }
        }
      }
    
     {k = $1 OFS $3 OFS $4}
    
     $2 ~ /singlet/{pairup(t,s,1)}
    
     $2 ~ /triplet/{pairup(s,t,-1)}
    

    我认为您可以通过减少使用单个数组来进一步简化,但没有时间处理它。

    【讨论】:

    • 对不起,我是个菜鸟,最后一部分给了我“:k:找不到命令”,这是一个 awk 函数吗?它看起来不像 bash?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多