用于将特定行从多个文件压缩到单个文件(以及删除部分复制行)的代码

时间:2015-07-05 16:13:03

标签: python python-3.x

首先,我对此非常陌生。过去几天我一直在阅读一些教程,但现在我已经达到了想要实现的目标。

为您提供长版:我在目录中有多个文件,所有文件都包含某些行中的信息(23-26)。现在,代码必须找到并打开所有文件(命名模式:*.tag),然后将第23-26行复制到新的单个文件中。 (并在每个新条目后添加一个新行......)。可选地,它还将从我不需要的每一行中删除特定部分:

  • C12b2

    - >需要删除C12b2(或类似版本)之前的所有内容。

    到目前为止,我已经设法将这些行从一个文件复制到一个新文件,但其余部分仍然没有找到我:(不知道格式化在这里如何工作)

    f = open('2.tag')     
    
    n = open('output.txt', 'w')
    
    for i, text in enumerate(f):
    
        if i >= 23 and i < 27:
    
            n.write(text)
    
        else:
    
            pass
    

    有人能给我一些建议吗?我不需要完整的代码作为答案,但是,不跳过解释的好教程似乎很难得到。

  • 4 个答案:

    答案 0 :(得分:1)

    你可以查看glob模块,它给出了一个与你提供的模式匹配的文件名列表,请注意这个模式不是正则表达式,它是shell样式模式(使用shell样式的通配符)

    glob的例子 -

    >>> import glob
    >>> glob.glob('*.py')
    ['a.py', 'b.py', 'getpip.py']
    

    然后,您可以遍历glob.glob()函数返回的每个文件。

    对于每个文件,您现在可以执行相同的操作。

    然后在编写文件时,您可以使用str.find()查找字符串C12b2的第一个实例,然后使用切片删除您不想要的部分。

    作为一个例子 -

    >>> s = "asdbcdasdC12b2jhfasdas"
    >>> s[s.find("C12b2"):]
    'C12b2jhfasdas'
    

    你可以为你的每一行做类似的事情,请注意如果只有一些行有C12b2的用例,那么你需要首先检查该字符串是否存在于该行中,然后再进行以上切片。示例 -

    if 'C12b2' in text:
        text = text[text.find("C12b2"):]
    

    您可以在将该行写入输出文件之前执行上述操作。

    此外,最好查看with语句,您可以使用它来打开文件,以便在完成处理后自动处理关闭文件。

    答案 1 :(得分:0)

    您可以realineswritelines使用ab作为行切片的行边界:

    with open('oldfile.txt', 'r') as old:
        lines = old.readlines()[a:b]
    
    with open('newfile.txt', 'w') as new:
        new.writelines(lines)
    

    答案 2 :(得分:0)

    使用glob package,您可以获得所有*.tag个文件的列表:

    import glob
    # ['1.tag', '2.tag', 'foo.tag', 'bar.tag']
    tag_files = glob.glob('*.tag')
    

    如果您使用with statement打开文件,则会在之后自动关闭:

    with open('file.tag') as in_file:
        # do something
    

    使用readlines()将整个文件读入一个行列表,然后可以将其切片:

    lines = in_file.readlines()[22:26]
    

    如果您需要在特定模式之前跳过所有内容,请使用str.split()分隔模式中的字符串并选取最后一部分:

    pattern = 'C12b2'
    clean_lines = [line.split(pattern, 1)[-1] for line in lines]
    

    看一下这个例子:

    >>> lines = ['line 22', 'line 23', 'Foobar: C12b2 line 24']
    >>> pattern = 'C12b2'
    >>> [line.split(pattern, 1)[-1] for line in lines]
    ['line 22', 'line 23', ' line 24']
    

    答案 3 :(得分:0)

    os之外不导入任何内容:

    #!/usr/bin/env python3
    import os
    # set the directory, the outfile and the tag below
    dr = "/path/to/directory"; out = "/path/to/newfile"; tag = ".txt"
    
    for f in [f for f in os.listdir(dr) if f.endswith(".txt")]:
        open(out, "+a").write(("").join([l for l in open(dr+"/"+f).readlines()[22:25]])+"\n")
    

    它做什么

    完全按照你的描述,它:

    • 从目录中的所有文件(即:已定义的扩展名)中收集已定义的行区域
    • 将这些部分粘贴到新文件中,并以新行分隔

    解释

    [f for f in os.listdir(dr) if f.endswith(".tag")]
    

    列出目录中特定扩展名的所有文件,

    [l for l in open(dr+"/"+f).readlines()[22:25]]
    

    读取文件的选定行

    open(out, "+a").write()
    

    写入输出文件,如果它不存在则创建它。

    如何使用

    • 将脚本复制到空文件中,并将其另存为collect_lines.py
    • 在head部分设置包含文件的目录,新文件的路径和扩展名
    • 使用以下命令运行它:

      python3 /path/to/collect_lines.py
      

    详细版本,附有说明

    如果我们&#34;解压缩&#34;上面的代码,这是发生的事情:

    #!/usr/bin/env python3
    import os
    #--- set the path to the directory, the new file and the tag below
    dr = "/path/to/directory"; out = "/path/to/newfile"; tag = ".txt"
    #---
    
    files = os.listdir(dr)
    for f in files:
        if f.endswith(tag):
            # read the file as a list of lines
            content = open(dr+"/"+f).readlines()
            # the first item in a list = index 0, so line 23 is index 22
            needed_lines = content[22:25]
            # convert list to string, add a new line
            string_topaste = ("").join(needed_lines)+"\n"
            # add the lines to the new file, create the file if necessary
            open(out, "+a").write(string_topaste)