从制表符分隔值文件中删除某些返回字符

时间:2012-07-10 14:25:41

标签: python postgresql

我在工作中遇到了一个问题,要求我将一些MASSIVE标签分隔值文件(比如8-15 GB .txt文件)打印到我的PostgreSQL数据库中,但是我遇到了问题。数据首先被格式化。基本上,我们给出数据的方式(不幸的是我们无法以更好的格式获取数据),会出现一些反斜杠并导致返回/换行。

因此,有一些行(数据行,制表符分隔符)被切割成多行,其中行n的最后一个字符是\,行n + 1的第一个字符是制表符。通常行n将被分解为1-3个额外的行(例如,行n以“\”结尾,行n + 1和n + 2以制表符开头,以“\”结束,行n + 3开始用标签)。

我需要编写一个可以处理这些巨大文件的脚本(这将在具有192 GB RAM的Linux服务器上运行)来查找以tab开头的行,然后删除返回(和“\ “无论它存在于何处”并保存文本文件。

总结一下,客户的日志记录程序将原始行N分为行n,n + 1,有时n + 2和n + 3(取决于行N中出现的\ n \ n \ n \ n \ n \ n字符数),我需要编写用于重新创建原始行N的python脚本。

3 个答案:

答案 0 :(得分:2)

#!/usr/bin/python

import re,sys

lastLine = None
incomplete = re.compile("\\\\+$")
indented = re.compile("^\\t")

for line in open(sys.argv[1]):
    line = line.rstrip()
    line = incomplete.sub("", line)
    if indented.match(line):
        lastLine += indented.sub("",line)
    else:
        if lastLine:
            print lastLine
            lastLine = None
        lastLine = line

print lastLine

基本上,我忽略了\,因为下一行的标签告诉你它仍然是一个延续。

答案 1 :(得分:1)

将“\ n”序列替换为“

”:

In [20]: a="blabla\tblabla\tblabla\\\n\tblabla\tblabla"

In [21]: print(a)
blabla  blabla  blabla\
    blabla  blabla

In [22]: a=a.replace('\\\n', '')

In [23]: print(a)
blabla  blabla  blabla  blabla  blabla

:)

答案 2 :(得分:0)

这是基于@ user665637的好答案。

#!/usr/bin/python

import re, sys

pat_incomplete = re.compile(r'\\\s*$')
pat_indented = re.compile(r'^\t')

try:
    _, fname_in, fname_out = sys.argv
except ValueError:
    print("Usage: python line_joiner.py <input_filename> <output_filename>")
    sys.exit(1)

with open(fname_in) as in_f, open(fname_out, "w") as out_f:
    lines = iter(in_f)
    try:
        line = next(lines)
        s = pat_incomplete.sub('', line)
    except StopIteration:
        print("Input file did not contain any data")
        sys.exit(2)

    for line in lines:
        line = pat_incomplete.sub('', line)
        if pat_indented.match(line):
            s += pat_indented.sub('',line)
        else:
            out_f.write(s)
            s = line
    out_f.write(s)

的变化:

  • 使用正常表达式的“原始字符串”,更容易阅读。

  • 从命令行参数中获取输出文件名并写入该文件。如果用户提供的参数数量错误,则打印一条消息并退出。当我们解包sys.argv以获取参数时,我们使用变量名_的约定来表示我们不关心的部分。

  • 不剥离行结尾,因此输出文件将具有与输入文件相同的行结尾。 (当连接线条时,它当然会剥离线条结尾以进行连接。)

  • 不会从输入中过滤掉空白行。这有点棘手,但通过创建一个迭代器并在其上调用next(),它在启动循环之前得到第一个输入行;因此s以有效值而非None开头,我们不必每次都要测试它是否打印。在已剥离的输入行上进行的原始if lastLine:测试不仅可以防止None的初始lastLine值,还可以从输入中过滤掉任何空行。

  • 如果必须在Python 3.0或Python 2.6中使用它,则不能使用with语句执行两次open()次调用;但你可以把它变成两个嵌套的with语句,每个语句都只有一个open()