2012-11-08 13 views
24

私はPythonを使って解析しようとしているファイルのディレクトリを持っています。もしそれらがすべて同じ拡張であったとしても、何らかの理由でそれらが元の拡張の後に連続した数値拡張で作成されても問題はありません。例:foo.log foo.log.1 foo.log.2 bar.log bar.log.1 bar.log.2 etc. foo.logはXML形式で、bar.logはXML形式ではありません。 foo.log.*foo.logファイルだけを読み込んで解析するための最善のルートは何ですか? bar.logファイルを読む必要はありません。以下は、私のコードは次のとおりです。os.listdir(パス)のファイル拡張子ワイルドカードを使用

import os 
from lxml import etree 
path = 'C:/foo/bar//' 
listing = os.listdir(path) 
for files in listing: 
    if files.endswith('.log'): 
     print files 
     data = open(os.path.join(path, files), 'rb').read() 
     tree = etree.fromstring(data) 
     search = tree.findall('.//QueueEntry') 

それはどんな.log.*ファイルを読み取らないと、パーサーが読み込まれるファイルにチョークが、XML形式ではないので、これは動作しません。ありがとう!

答えて

41

たぶんglobモジュールはあなたを助けることができる:これはあなたのbashのような正規表現あげる

import glob 

listing = glob.glob('C:/foo/bar/foo.log*') 
for filename in listing: 
    # do stuff 
+1

OPがPOSIXシェルではなくWindowsの 'cmd'シェルでワイルドカードのように動作することを期待している場合、それは完全ではありません...しかし、彼のユースケースには十分であり、私はこれが正しい答えだと思います。 – abarnert

+0

それは、ありがとう! –

+0

'〜'を展開してくれなかったことに感謝しています - どういうわけか、Pythonはすべてのシステムコマンドをunixよりも悪化させます... – user3467349

3

import glob 
print(glob.glob("/tmp/o*")) 

また、ディレクトリ全体をos.listdir可能性を、そして捨てます再モジュールを介して正規表現と一致しないファイル

+0

Globワイルドカードは正規表現ではありません。まあ、技術的に言えば、それは正規の言語ですが、人々が "正規表現"と言うときに考えるものではなく、正規表現ではないと明示的に言っています。 '/ tmp/o *'は ''/tmp/'の後に' o'の0個以上のインスタンスが続くことを意味しません。 [Globbing](http://tldp.org/LDP/abs/html/globbingref.html)を参照してください。 – abarnert

+1

私はずっと前にcomp.unix.shellで学びました。* ixにはグロブパターンを含む多くの種類の正規表現があります。 "Advanced Bash Scripting Guide"は、bashドキュメントの一部ではありません。これはperlの熱心な人が書いたスクリードで、おそらくperlの正規表現は誰でも使うはずの正規表現だと思っています。 – dstromberg

+0

[globsの公式のPOSIXのドキュメント](http://pubs.opengroup.org/onlinepubs/7908799/xsh/glob.html)はこちらです。それは "正規表現"、またはそれと似たようなものはどこにもありません。ここには[正規表現のPOSIXの公式文書](http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.html)があります。これは、正規表現(BREとERE)として数えられるちょうど2つの言語を明確に定義します。 'bash'、' linux'/'glibc'、' * BSD'などのドキュメントにも同様の言葉があります。 – abarnert

10

ファイルfoo.log.*foo.logのファイルを読み込んで解析するには、どのような方法が最適ですか? bar.logファイルは読み込む必要はありません。

あなたのコードこれを行います。

if files.endswith('.log'): 

をあなたは自分の英語の説明が少し間違っているのPythonに翻訳しました。 Pythonで書いているのは、 "*.logファイルのみを読み込み、解析する"です。つまり、bar.logが含まれ、foo.log.1は含まれていません。限り、余分なドットとfoo.log.という名前のファイルが(存在しないよう

if files == 'foo.log' or files.startswith('foo.log.'): 

そして、あなたはそれについて考える場合、:

しかし、あなたが第二のためと思えば、あなたの英語の記述は、Pythonに直接翻訳することができます)あなたはスキップしたいことを、あなたは1に2例を折りたたむことができます。

if files.startswith('foo.log'): 

ただし、POSIXシェル、foo.log*マッチまったく同じことについて何を知っていれば。これはワイルドカードが拡張子を特別に扱うWindowsシェルにとっては当てはまりません。そのため*の代わりに*.*と入力しなければなりません。そして、PythonにはWindowsの場合でもglobというPOSIXスタイルのワイルドカードを実行するモジュールが付属しています。これを使用する方法については、stranacの答えを参照してください。

私はglob答えが手動でより良いフィルタlistdirだと思います。簡単ですが、あなたの質問のタイトルが何をしたいと言っているのか(より具体的には、os.listdirで作業することを期待していましたが、代わりにglob.globで作業します)、より柔軟です。したがって、ワイルドカードの2つのわずかに異なる意味で混乱することを心配している場合を除き、私はこれを受け入れることをお勧めします。

+0

+1すばらしい説明 –

関連する問題