1

職場で問題が発生し、タブで区切られたMASSIVE値ファイル(8〜15 GBの.txtファイルなど)をPostgreSQL DBに挿入する必要がありますが、データのフォーマット方法に問題があります。そもそも。基本的に、データが与えられる方法(そして残念ながら、より良い形式でデータを取得することはできません)には、いくつかのバックスラッシュが表示され、改行/改行が発生します。

したがって、複数の行に分割される行(データの行、tab-delim)があります。ここで、行nの最後の文字は\であり、行n+1の最初の文字はタブです。通常、行nは1〜3行に分割されます(たとえば、行nは「\」で終わり、行n+1とn+2はタブで始まり、行n + 3は「\」で終わり、行n+3は始まります。タブ付き)。

これらの巨大なファイル(192 GBのRAMを搭載したLinuxサーバーで実行されます)を処理できるスクリプトを記述して、タブで始まる行を探し、戻り値(および「\」)を削除する必要があります。存在する)そしてテキストファイルを保存します。

要約すると、顧客のロギングプログラムは、元の行Nを行n、n + 1、場合によってはn+2とn+3に分割します(行Nに表示される\文字の数によって異なります)。Pythonスクリプトを作成する必要があります。元の行Nを再作成します。

4

3 に答える 3

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

基本的に、次の行のタブはそれがとにかく継続であるとあなたに告げるので、私は最後の\を無視しています。

于 2012-07-10T15:26:16.923 に答える
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

:)

于 2012-07-10T14:33:35.753 に答える
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:保護するだけでなく、入力から空白行を除外します。NonelastLine

  • これをPython3.0またはPython2.6で使用する必要がある場合、 2つの呼び出しを行うwithステートメントを作成することはできません。open()ただし、それを2つのネストされたwithステートメントに変換することができ、それぞれが1つのを実行しopen()ます。

于 2012-07-10T18:53:13.113 に答える