2016-10-19 4 views
0

実際に欲しいものを得る前にランダムなテキストを含むテキストファイルがある場合、ファイルポインタをそこに移動するにはどうすればいいですか?Pythonで文字をシークする方法で行をスキップする方法

例えば私のテキストファイルは次のようになりますと言う:私はもののラインにファイルポインタを移動するにはどうすればよい

#foeijfoijeoijoijfoiej ijfoiejoi jfeoijfoifj i jfoei joi jo ijf eoij oie jojf 
#feoijfoiejf ioj oij  oi jo ij i joi jo ij oij #### oijroijf 3## # o 
#foeijfoiej i jo i iojf 3 ## #io joi joij oi j## io joi joi j3# 3i ojoi joij 
# The stuff I care about 

(ハッシュタグは、実際のテキストファイルの一部である)

I気にして、私はどのように私に行の番号を教えて、そこにファイルの読書を開始するPythonを得るだろうか?

私は最後のハッシュタグが入っている行を見つけてそこから読んでみたが、まだハッシュタグを取り除いて行番号が必要な場合があります。

+0

あなたはそうしているで始まるすべての行をスキップするので、 '例えば#1 F'は、各行の先頭に起こるから動作するように一貫性のある何かを見つける必要がありますifステートメント。あなたが作業できる他のパターンを見つけることができますか? – Sarcoma

+0

問題は#fが必ずしも各行の先頭にあるわけではなく、常に行頭にハッシュタグがあることです。 単なる文字列のように.rfind( '#')を使いたいのですが、文書全体を文字列にすることなくテキスト文書全体に.rfind()を適用する方法がわかりません。 – Destroxia

+0

私はちょうど各行をループし、それぞれの最初の 'char'をチェックします。もしそれが'# 'なのか、他の何かが予測できない場合、内容をヒットしてそこから読み始めます。 – Sarcoma

答えて

0

readlines機能を試してください。これは、各行を含むリストを返します。 forループを使用して各行を解析し、必要なものを探してから、リスト内の索引を使用して行番号を取得できます。例えば:

with open('some_file_path.txt') as f: 
    contents = f.readlines() 
object = '#the line I am looking for' 
for line in contents: 
    if object in line: 
     line_num = contents.index(object) 

はちょうどreplace機能を使用し、シャープ記号を取り除くために。例えば。 new_line = line.replace('#','')

+0

ファイルのすべての行を一度にメモリに読み込みます。すべての行を必要としない場合でも、その一部だけを処理したい場合でも残りのファイルをスラップします。 OPが迷惑メールの直後を目指すことに関係している場合、おそらく不要なI/O /メモリの使用を避けようとしています。これは何もしません。 – ShadowRanger

0

迷惑データのサイズや迷惑メールのスキャンを知らなくても、直接検索することはできません。あなたが実際に、適切に配置ファイルディスクリプタをする必要はありません場合は

import itertools 

# Or def a regular function that returns True until you see the line 
# delimiting the beginning of the "good" data 
not_good = '# The stuff I care about\n'.__ne__ 

with open(filename) as f: 
    for line in itertools.dropwhile(not_good, f): 
     ... You'll iterate the lines at and after the good line ... 

:しかし、それはすべての残りの行を反復処理した後、あなたが「良い」データが表示されるまでラインを破棄するitertools.dropwhileでファイルをラップするためにあまりにも難しいことではありませんただの線は、このバリアントは動作するはずです:あなたは本当に(というだけのオフセットを必要とするよりも)それを必要とする場合

import io 

with open(filename) as f: 
    # Get first good line 
    good_start = next(itertools.dropwhile(not_good, f)) 

    # Seek back to undo the read of the first good line: 
    f.seek(-len(good_start), io.SEEK_CUR) 

    # f is now positioned at the beginning of the line that begins the good data 

あなたは、実際の行番号を取得するには、これを微調整することができます。しかし、あまり読みにくいので、明示的な反復をenumerateで実行する必要がある場合は、より意味をなさないかもしれません。あなたのためのPythonの仕事を作るための方法は次のとおりです。

from future_builtins import map # Py2 only 
from operator import itemgetter 

with open(filename) as f: 
    linectr = itertools.count() 
    # Get first good line 
    # Pair each line with a 0-up number to advance the count generator, but 
    # strip it immediately so not_good only processes lines, not line nums 
    good_start = next(itertools.dropwhile(not_good, map(itemgetter(0), zip(f, linectr)))) 

    good_lineno = next(linectr) # Keeps the 1-up line number by advancing once 

    # Seek back to undo the read of the first good line: 
    f.seek(-len(good_start), io.SEEK_CUR) 

    # f is now positioned at the beginning of the line that begins the good data 
関連する問題