使用 awk/ bash 或 R 解析多行结果文本文件

Parse multi line result text file with awk/ bash or R

我正在尝试使用以下内容解析文本文件:

  The MELTING results are :

 Enthalpy : -181,100 cal/mol ( -756,998 J /mol)

 Entropy : -467.3 cal/mol-K ( -1,953.31 J /mol-K)

 Melting temperature : 75.13 degrees C.


  The MELTING results are :

 Enthalpy : -170,800 cal/mol ( -713,944 J /mol)

 Entropy : -444 cal/mol-K ( -1,855.92 J /mol-K)

 Melting temperature : 70.6 degrees C.

我正在尝试解析,以便每个条目得到一行,以焓(任何一个或两个)、熵(任何一个或两个)和熔化温度作为列。 我尝试使用

awk '=="Enthalpy" {print [=12=]}' file.txt > a 

熵和熔化温度类似,合并列并进行相应解析。 但是,我注意到,

awk '=="Enthalpy" {print [=13=]}' file.txt | wc -l 

结果 98181,熵相似,但熔化温度为 92418。

独立组合这些值,不知道少了哪个。有没有办法将所有这三个一起解析,并为缺失的熔化温度提供 NA 或固定值?如果可能,使用 awk (bash)

匹配第一个单词时,将每一行分配给一个变量。然后,当您匹配开始新块的 MELTING results 行时,打印变量,用 NA 替换空值。然后在处理下一个块之前清空这些值。

最后,打印 END 代码中最后一个块的行,因为它后面没有 MELTING results 行。

awk ' == "Enthalpy" { enth = [=10=] }
      == "Entropy" { entr = [=10=] }
      == "Melting" { melt = [=10=] }
     /MELTING results/ && NR > 1 { 
        printf("%s\n%s\n%s\n", (enth ? enth : "NA"), (entr ? entr : "NA"), (melt ? melt : "NA"));
        enth = entr = melt = "";
     }
     END {
        printf("%s\n%s\n%s\n", (enth ? enth : "NA"), (entr ? entr : "NA"), (melt ? melt : "NA"));
     }' file.txt > a

1) 如果 R 标签意味着你想要一个 R 解决方案,并且假设你想保留每行的第一个数字,那么为了说明它,我们将使用可重复生成的文件在末尾的注释中,我们添加了缺少字段的记录。

首先将其读入一个包含 V1 和 V2 列的 2 列数据框,将 The Melting ... V1 字段替换为空字符串,并将 V2 中的第一个 space 及其后的所有内容替换为空字符串。同时从 V2 中删除所有逗号。将它重新粘贴到一起,此时现在是 Debian 控制格式 (dcf)。现在使用 read.dcf 读取它并将其转换为数字矩阵。 (需要 textConnectionname="" 参数来规避该函数中发生在长管道中的错误。这是 discussed on r-devel 并且它似乎已经在 R 的开发版本中修复.)

没有使用包。

"melting.txt" |>
  read.table(sep = ":", strip.white = TRUE) |>
  transform(V1 = sub("The MELTING.*", "", V1),
    V2 = sub(" .*", "", gsub(",", "", V2))) |>
  with(paste0(V1, ifelse(nchar(V1), ": ", ""), V2)) |>
  textConnection(name = "") |>
  read.dcf() |>
  type.convert(as.is = TRUE)

给出这个数字矩阵:

     Enthalpy Entropy Melting temperature
[1,]  -181100  -467.3               75.13
[2,]  -170800  -444.0               70.60
[3,]  -181100      NA               75.13
[4,]       NA  -444.0               70.60

2) 或者,混合 awk/R 解决方案如下。假设 melting.awk 在当前目录中,包含:

# convert to dcf
BEGIN { FS = " : "; OFS = ": " }
/MELTING/ { print ""; next }
/:/ { sub(/^ */, "", ); gsub(/ .*|,/, "", ); print }

然后假设 gawk 在路径 运行 上来自 R。(这可能也适用于 awk,但我只用 gawk 尝试过。)

"gawk.exe -f melting.awk melting.txt" |>
  pipe() |>
  read.dcf() |>
  type.convert(as.is = TRUE)

备注

Lines <- "  The MELTING results are :

 Enthalpy : -181,100 cal/mol ( -756,998 J /mol)

 Entropy : -467.3 cal/mol-K ( -1,953.31 J /mol-K)

 Melting temperature : 75.13 degrees C.


  The MELTING results are :

 Enthalpy : -170,800 cal/mol ( -713,944 J /mol)

 Entropy : -444 cal/mol-K ( -1,855.92 J /mol-K)

 Melting temperature : 70.6 degrees C.

  The MELTING results are :

 Enthalpy : -181,100 cal/mol ( -756,998 J /mol)

 Melting temperature : 75.13 degrees C.


  The MELTING results are :

 Entropy : -444 cal/mol-K ( -1,855.92 J /mol-K)

 Melting temperature : 70.6 degrees C."

cat(Lines, file = "melting.txt")