【问题标题】:awk in python: How to use awk scripts in a python class?python中的awk:如何在python类中使用awk脚本?
【发布时间】:2011-10-20 23:35:01
【问题描述】:

我正在尝试使用 python 运行 awk 脚本,以便处理一些数据。

有没有办法让 awk 脚本在 python 类中运行,而不使用系统类来调用它作为 shell 进程?我运行这些 python 脚本的框架不允许使用子进程调用,所以我要么想办法在 python 中转换我的 awk 脚本,要么在可能的情况下在 python 中运行 awk 脚本。

有什么建议吗?我的 awk 脚本基本上读取一个文本文件并隔离包含特定化合物的蛋白质块(输出由我们的框架生成;我在下面添加了一个示例,说明它的外观)并将它们隔离并打印出来不同的文件。

    buildProtein compoundA compoundB
    begin fusion
    Calculate : (lots of text here on multiple lines)
    (more lines)
    Final result - H20: value CO2: value Compound: value 
    Other Compounds X: Value Y: value Z:value

    [...another similar block]

例如,如果我构建了一种蛋白质,我需要查看最终结果行中是否有 CH3COOH,如果有,我必须从命令“buildProtein”开始获取整个块,直到下一个区块的开始;并将其保存在文件中;然后移动到下一个,看看它是否有我正在寻找的化合物......如果没有,我跳到下一个,直到文件末尾(文件有多次出现的化合物我搜索,有时它们是连续的,而有时它们与没有化合物的块交替。

我们非常欢迎任何帮助;现在我头疼了几个星期,在发现这个网站后,我决定寻求一些帮助。

提前感谢您的好意!

【问题讨论】:

    标签: python awk


    【解决方案1】:

    如果您不能使用 subprocess 模块,最好的办法是在 Python 中重新编码您的 AWK 脚本。为此,fileinput 模块是一个很棒的转换工具,具有类似 AWK 的感觉。

    【讨论】:

    • 非常感谢雷蒙德。然后我应该加载整个文件,使用文件输入处理它,然后将输出保存在外部文件中吗?我想为我非常独特的案例找到一个合适的例子很难:)
    • @user1006198:您的情况并非独一无二。只是你的设计很糟糕,因为 AWK 太糟糕了。加载整个文件。处理整个文件。保存整个输出。完全丢弃 AWK。仅从相关的“计算”开始,忽略 AWK 限制的伪影。 Python(在许多方面)会变得更简单。既然是新的,当然要先学会,让它看起来很复杂。
    • :-) Fileinput 将让您像 AWK 一样逐行处理输入。您可以使用“print >> somefile, some_line_of_text”将输出发送到另一个文件。
    • 我明白了;我不知道这个模块,现在阅读它的工作原理似乎非常相似;感谢您指出雷蒙德!
    • 是物流和时间的问题;一件事是我为日志编写了一个简单的解析器;另一个是改变他们的立场以做出不同的输出:)
    【解决方案2】:

    Python's re module 可以提供帮助,或者,如果您不介意正则表达式而只需要进行一些快速的字段分隔,您可以使用 the built in str .split() .find() 函数。

    【讨论】:

    • 感谢 Aphex;试图写一个 RE 但惨遭失败;因为我对纯RE不太了解;使用 AWK 很容易找到和隔离块,因为您可以打开和关闭 print 语句,但是使用纯 RE 我不确定如何处理它。主要目标是在块中找到化合物的出现,如果化合物在其中,则保存整个块,因此这不仅需要在块中找到某些东西(这对我来说很容易),而且一次你找到了出现,从第一行到下一个块的第一行获取所有内容,依此类推
    • @user1006198:评论是一个糟糕的地方来解释你的真正的问题。考虑更新您的问题以解释您的问题。例子有帮助。 awk 的 /pattern/ code 构造使用 RE。它在 Python 中转换为 if re.match(r'pattern',line): code。标点符号略多于 AWK。模式中的正则表达式语言相同。
    • 另外,在我作为 UNIX 管理员的短暂工作期间,我最常使用 awk 来进行字段分隔 - 例如在 awk -F ',' 中分隔逗号分隔的字段等等。这也可以在 python 中轻松完成,只需使用readlines() 读取文件并遍历每一行并使用.split()
    • 确实很难在cmets中添加信息;这就是为什么我尽我所能在主帖中陈述我的问题的原因;如果不清楚,请告诉我,我会非常乐意让它更具可读性(英语不是我的第一语言,尽我所能)
    【解决方案3】:

    我刚刚开始学习 AWK,所以我无法在这方面提供任何建议。但是,对于一些可以满足您需要的 python 代码:

    class ProteinIterator():
        def __init__(self, file):
            self.file = open(file, 'r')
            self.first_line = self.file.readline()
        def __iter__(self):
            return self
        def __next__(self):
            "returns the next protein build"
            if not self.first_line:     # reached end of file
                raise StopIteration
            file = self.file
            protein_data = [self.first_line]
            while True:
                line = file.readline()
                if line.startswith('buildProtein ') or not line:
                    self.first_line = line
                    break
                protein_data.append(line)
            return Protein(protein_data)
    
    class Protein():
        def __init__(self, data):
            self._data = data
            for line in data:
                if line.startswith('buildProtein '):
                    self.initial_compounds = tuple(line[13:].split())
                elif line.startswith('Final result - '):
                    pieces = line[15:].split()[::2]   # every other piece is a name
                    self.final_compounds = tuple([p[:-1] for p in pieces])
                elif line.startswith('Other Compounds '):
                    pieces = line[16:].split()[::2]   # every other piece is a name
                    self.other_compounds = tuple([p[:-1] for p in pieces])
        def __repr__(self):
            return ("Protein(%s)"% self._data[0])
        @property
        def data(self):
            return ''.join(self._data)
    

    我们这里有一个 buildprotein 文本文件的迭代器,它一次返回一个蛋白质作为 Protein 对象。这个Protein 对象足够聪明,可以知道它的输入、最终结果和其他结果。如果文件中的实际文本与问题中表示的不完全相同,您可能需要修改一些代码。以下是对代码的简短测试以及示例用法:

    if __name__ == '__main__':
        test_data = """\
    buildProtein compoundA compoundB
    begin fusion
    Calculate : (lots of text here on multiple lines)
    (more lines)
    Final result - H20: value CO2: value Compound: value 
    Other Compounds X: Value Y: value Z: value"""
    
        open('testPI.txt', 'w').write(test_data)
        for protein in ProteinIterator('testPI.txt'):
            print(protein.initial_compounds)
            print(protein.final_compounds)
            print(protein.other_compounds)
            print()
            if 'CO2' in protein.final_compounds:
                print(protein.data)
    

    我没有费心保存值,但如果您愿意,可以添加它。希望这会让您继续前进。

    【讨论】:

      猜你喜欢
      • 2018-05-08
      • 2013-05-16
      • 2021-10-19
      • 2020-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多