2017-02-26 7 views
-1

私はPythonを初めて使用しています。私は何千ものCSVファイルを持っています。そこには、数値データが記録された後に来るテキストのグループがあり、テキストで始まるすべての行を削除したいと思います。たとえば、正規表現を使用してCSVファイルから最後の行を含む「文字列」を削除する

col 1 col 2 col 3 
-------------------- 
10  20  30 
-------------------- 
45  34  56 
-------------------- 
Start 8837sec 9items 
-------------------- 
Total 6342sec 755items 

すべてのcsvファイルのテキストは、「開始」列1で始まるのが良いことです。私は後で "スタート"と言う行を含め、すべての行を削除することをお勧めします。

import csv, os, re, sys 


fileList = [] 

pattern = [r"\b(Start).*", r"\b(Total).*"] 

for file in files: 
    fullname = os.path.join(cwd, file) 

    if not os.path.isdir(fullname) and not os.path.islink(fullname): 
     fileList.append(fullname) 


for file in fileList: 
    try: 
     ifile = open(file, "r") 
    except IOError: 
     sys.stderr.write("File %s not found! Please check the filename." %(file)) 
     sys.exit() 
    else: 
     with ifile: 
      reader = csv.reader(ifile) 
      writer = csv.writer(ifile) 
      rowList = []  
      for row in reader: 
       rowList.append((", ".join(row))) 

     for pattern in word_pattern: 
      if not (re.match(pattern, rowList) 
       writer.writerow(elem) 

このスクリプトを実行した後、それは私に空白のcsvファイルを与える:ここで

は、私がこれまで持っているものです。どのようなアイデアを変更するか?

+0

この例では、「writer」という名前の変数はありません。あなたは例外と何も書かれていないはずです。 'START'の後にすべてを取り除きたいだけですか?あなたはそれのためにCSVは必要ありません。 – tdelaney

+0

CSVのエンコーディングとは何ですか?それはASCIIかUTF-8ですか? – tdelaney

+0

コードにwriter文を追加しました。 CSVファイルのエンコーディングはASCII形式です。 – SalN85

答えて

0

これにはCSVリーダーは必要ありません。単にオフセットを見つけてファイルを切り詰めることができます。ファイルをバイナリモードで開き、複数行の正規表現を使用してテキスト内のパターンを見つけ、そのインデックスを使用します。

import os 
import re 

# multiline, ascii only regex matches Start or Total at start of line 
start_tag_finder = re.compile(rb'(?am)\nStart|\nTotal').search 

for filename in files: # TODO: I'm not sure where "files" comes from... 
    # NOTE: no need to join cwd, relative paths do that automatically 
    if not os.path.isdir(filename) and not os.path.islink(filename): 
     with open(filename, 'rb+') as f: 
      # NOTE: you can cap file size if you'd like 
      if os.stat(filename).st_size > 1000000: 
       print(filename, "overflowed 10M size limit") 
       continue 
      search = start_tag_finder(f.read()) 
      if search: 
       f.truncate(search.start()) 
+0

こんにちはtdelaney ...ありがとう、それは働く:)。簡単な質問:文字列のメソッド(string.startswith(keywords))は、キーワードがkeyword =( "Search"、 "Total")の場合も同様ですか? – SalN85

+0

この例では、行単位ではなくブロック単位でファイルを処理するので、 'startswith'は動作しませんが、f.read()で' \ nStart "は実行されます。正規表現を使用すると、1つのC拡張モジュールで複数のキーワードを一度に確認できます。ほとんどの最新のコンピュータでは、ファイルを読み込むために数メガバイトのRAMを焼くのは簡単ではありません。あなたは行ごとに読むことができ、 'startswith'も行うことができます。 – tdelaney

0

私はあなたが一緒にあなたのfileListを取得した後、すべてのためにこれをしようと:

for file in fileList: 
    keepRows = [] 
    open(file, 'r') as oFile: 
    for row in oFile: 
     if row[0] != "Start": 
      keepRows += row 
     else: 
      oFile.close() 
    with open(file, 'wb+') as nFile: 
    writer = csv.writer(nFile, delimiter=',') 
    writer.writerow([keepRows]) 

これは、元のファイルを開き、あなたが望んでいる行を取得し、それを閉じ、w+でそれを開きます。これにより、ファイル名が保持されたまま上書きされますが、切り捨てによってファイルが消去され、クリアされたファイルの各行に保存したい各行が書き込まれます。

また、あなたは各CSV行うための新しいファイルを作成することができます。これはappendあるので、

for file in fileList: 
    keepRows = [] 
    with open(file, 'r') as oFile, open('new_file.csv', 'a') as nFile: 
    for row in oFile: 
     if row[0] != "Start": 
      keepRows += row 
     else: 
      oFile.close() 
    for row in keepRows: 
     nFile.write(row) 

aとのオープニングは、次の行のたびにカーソルを置きます。 .writerowメソッドの前にユーザーが反復可能である理由は、objectの場合、はkeepRowsで、appendの場合はiterablesが不要でグループ内の各項目を独自の列に書き込んで次の行と同じことを行う。

EDITbinary file mode.writer()ための更新構文。

+0

hi pstatix、ご協力いただきありがとうございます。私は "スタート"の後に何かを隔離することによって新しいリストを作成するためのあなたの最初の方法を理解しました。しかし、ファイルの上書きを開始して名前を保持すると、切り捨てオプションが表示されません。また、私はcsv.writer()が引数として 'nfile'を取るべきだと思いますか? – SalN85

+0

@Salil Nanda、 '.writer()'の部分を正しいものとして更新しました。ファイルオブジェクトを提供するのを忘れました。 truncateオプションは 'open()'関数を呼び出すモードに基づいています。 'w'を使うと' b'を使った 'write'はファイルが' binary'モードで開かれたことを意味し、 '+'を使うと 'read-write'更新能力を有効にします。デフォルトでは、 'w +'はファイルを0バイトに上書きします(つまり、それを切り捨てます)。これは、あなたが望む行を集めた後に 'wb +'モードを呼び出す理由です。 'b'を使う理由は、Windows OSがファイルの' new line'を解釈できるようにするためです。 – pstatix

+0

@サリル・ナンドラ、応答が長すぎます。以下は 'open()'モードの参考資料です:1)http://stackoverflow.com/questions/16208206/confused-by-python-file-mode-w。 2)https://docs.python.org/2/library/functions.html#open – pstatix

関連する問題