【问题标题】:awk or sed command to parse data from multiple file and combine them using a specific formatawk 或 sed 命令解析来自多个文件的数据并使用特定格式组合它们
【发布时间】:2017-04-18 15:15:28
【问题描述】:

我需要解析使用不同参数运行的化学程序的输出,并以特定格式组合感兴趣的信息。

程序的每个输出文件如下表所示,它给出了特定 pH 值(此处为 pH=0)下质子化和非质子化物种(残基)的数量:

   Residue Number     State  0     State  1     State  2     State  3     State  4
-----------------------------------------------------------------------------------
Residue: GL4 7    0.000410 (0) 0.453512 (1) 0.004275 (1) 0.535908 (1) 0.005895 (1)
Residue: HIP 15   0.900000 (2) 0.080000 (1) 0.020000 (1)
Residue: AS4 18   0.010085 (0) 0.486042 (1) 0.004335 (1) 0.495922 (1) 0.003615 (1)
Residue: GL4 35   0.000000 (0) 0.581343 (1) 0.000360 (1) 0.368002 (1) 0.050295 (1)
Residue: AS4 48   0.022640 (0) 0.520073 (1) 0.018440 (1) 0.425152 (1) 0.013695 (1)
Residue: AS4 52   0.038725 (0) 0.517533 (1) 0.113676 (1) 0.280601 (1) 0.049465 (1)
Residue: AS4 66   1.000000 (0) 0.000000 (1) 0.000000 (1) 0.000000 (1) 0.000000 (1)
Residue: AS4 87   0.004295 (0) 0.439747 (1) 0.010535 (1) 0.524678 (1) 0.020745 (1)
Residue: AS4 101  0.000105 (0) 0.504673 (1) 0.013110 (1) 0.478517 (1) 0.003595 (1)
Residue: AS4 119  0.014240 (0) 0.488767 (1) 0.007100 (1) 0.483272 (1) 0.006620 (1)

对于每个 pH 值,我都有一个这样的文件(所有文件都有完全相同的残基和状态,只有种群发生了变化)。现在我想提取所有残基的去质子化部分。去质子化部分对应于编号后有 (0) 的种群:例如,在 GL4 7 在 pH=0 的情况下,它是 0.000410(对应于状态 0),对于 AS4 66,它是 1.00000。事实上,除了 HIP 15 之外,所有残基都是状态 0:在这种情况下,去质子化的分数用 (1) 表示,对应于状态 1 和 2。在上面的示例中,它是 0.080000 + 0.020000 = 0.1。

然后我需要将来自不同文件的这些信息合并到一个文件中,如下所示:

#     pH     GLU7    HIS15    ASP18    GLU35    ASP48    ASP52    ASP66    ASP87   ASP101   ASP119
   0.000    0.000    0.100    0.010    0.000    0.023    0.039    1.000    0.004    0.000    0.014
   1.000    0.006    0.140    0.098    0.000    0.276    0.312    1.000    0.015    0.002    0.069

每一列对应一个残基,每一行对应一个pH值(即来自单个文件的信息,这里我只显示来自两个文件的信息)。

我试图想出一些 awk 单行,但我是初学者,我不知道如何继续。实际上,我不知道 awk 是否是这项工作的最佳工具。也许 sed 和 grep 或 python 会更好。 我将需要对许多不同的输出进行多次这种解析(但尽管残基会发生变化,但它们看起来都一样)所以我想有一种方法可以使其自动化但具有一定的灵活性。

如果您有任何建议或cmets,请不要犹豫,如果您能帮助我解决这个问题,我将不胜感激。

非常感谢!

【问题讨论】:

  • awk 不是一个好的解决方案,因为它总是一次只能处理一个文件并且不能合并文件。我建议使用 Python pandas DataFrames。
  • 为什么(1) 表示HIP 15 的去质子化分数?一般规则是去质子化分数是以最小数为指标的那些状态的总和吗?
  • @mhawke,是的,这确实是一个很好的观点:他去质子化的分数是以最小数量为指标的那些状态的总和。这可以以某种方式用于提取感兴趣的信息吗?

标签: python parsing awk sed grep


【解决方案1】:

您可以使用 for 循环将所有文件分类到文件,并使用 Stackoverflow 中的先前解决方案将行转置为列。

An efficient way to transpose a file in Bash

【讨论】:

  • 谢谢,但这不是简单的换位,我需要从原始文件中提取特定位
【解决方案2】:

目前尚不完全清楚您想要什么,但 python 的 split 功能可能对您有用。如果在没有任何参数的情况下调用,它会根据空格进行拆分(将多个空格合并为一个)

以这一行为例,

Residue: GL4 7    0.000410 (0) 0.453512 (1) 0.004275 (1) 0.535908 (1) 0.005895 (1)

可以这样拆分,

a = 'Residue: GL4 7    0.000410 (0) 0.453512 (1) 0.004275 (1) 0.535908 (1) 0.005895 (1)'
l = a.split()
print l

['Residue:', 'GL4', '7', '0.000410', '(0)', '0.453512', '(1)', '0.004275', '(1)', '0.535908', '(1)', '0.005895', '(1)']

然后,您可以访问所需的值并对其进行处理。在字符串上调用 float 和 int (例如,float('0.00410') 应该为您将它们转换为数字。对于 '(1)',您可以执行 int('(1)'[1:-1])

【讨论】:

    【解决方案3】:

    这个awk 脚本应该可以帮助您入门。为了获得所需的输出,您必须将文件名替换为相应的 pH 值。我省略了不包含零状态的行,因为您没有指定如何处理这些。

    /^   Residue/ || /^-----/ { next; }
    
    {
        filenames[FILENAME] = 1;
        columns[$2 " " $3] = 1;
        for (i = 5; i <= NF; i = i + 2) {
            if ($i == "(0)") {
                data[$2 " " $3, FILENAME] = $(i-1);
            }
        }
    }
    
    END {
        printf("%10s", "filename");
        for (col in columns) {
            printf("%10s", col);
        }
        print "";
        for (filename in filenames) {
            printf("%10s", filename);
            for (col in columns) {
                printf("%10s", data[col, filename]);
            }
            print "";
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-12
      • 1970-01-01
      • 1970-01-01
      • 2016-07-31
      • 2014-12-01
      • 2012-04-16
      • 2022-10-04
      • 2016-12-24
      相关资源
      最近更新 更多