グロブ除外パターン


103

eee2314asd3442...、eph。の中にたくさんのファイルがあるディレクトリがあります。

私はで始まるすべてのファイル除外したいephglob機能を。

どうすればいいですか?

回答:


147

globのパターンルールは正規表現ではありません。代わりに、標準のUnixパス拡張ルールに従います。特殊文字はごくわずかです。2つの異なるワイルドカードと文字範囲が[ globから]サポートされています。

したがって、パターンを含むいくつかのファイルを除外できます。
たとえば_、globでマニフェストファイル(で始まるファイル)を除外するには、次のコマンドを使用できます。

files = glob.glob('files_path/[!_]*')

10
これは公式ドキュメントにある必要があります。誰かがこれをdocs.python.org/3.5/library/glob.html#glob.globに
Vitaly Zdanevich 2016

6
グロブパターンは、OPによって設定された要件を直接満たすことができないことに注意してください。で始まるファイルのみを除外しますがeph、それ以外のもので始めることができます。たとえば[!e][!p][!h]で始まるファイルを除外しますeee
MartijnPieters

60

セットを差し引くことができます:

set(glob("*")) - set(glob("eph*"))

3
本当に面白い解決策!しかし、私の場合は、2回読み取るのに非常に時間がかかります。また、フォルダの内容がネットワークディレクトリで大きい場合、再び遅くなります。しかし、いずれにせよ、本当に便利です。
Anastasios Andronidis 2014

オペレーティングシステムはファイルシステム要求をキャッシュする必要があるので、それほど悪くはありません:)
neutrinus 2014

これを自分で試してみましたが、TypeErrorが発生しました:-: 'list'および 'list'のサポートされていないオペランドタイプ
Tom Busby 2014

1
@TomBusbyそれらをセットに変換してみてください:(set(glob("*")) - set(glob("eph*")) そして「eph *」の終わりに*注意してください)
Jaszczur 2014

2
補足として、globはセットではなくリストを返しますが、この種の操作はセットでのみ機能するため、ニュートリノがそれをキャストするのはなぜですか。:あなたはそれがリストを維持する必要がある場合は、単にキャストで操作全体を包むlist(set(glob("*")) - set(glob("eph")))
ネイサン・スミス

48

glob関数でパターンを除外することはできません。グロブは包含パターンのみを許可します。グロブ構文は非常に制限されています([!..]文字クラスでさえ文字と一致する必要があるため、クラスに含まれないすべての文字の包含パターンです)。

独自のフィルタリングを行う必要があります。リスト内包表記は通常、ここでうまく機能します。

files = [fn for fn in glob('somepath/*.txt') 
         if not os.path.basename(fn).startswith('eph')]

3
iglob完全なリストがメモリに保存されないようにするには、ここを使用してください
Eugene Pankov 2014年

3
@Hardex:内部的に、とにかくiglobリスト生成します; フィルタを怠惰に評価するだけです。メモリフットプリントを削減するのに役立ちません。
MartijnPieters

@Hardex:ディレクトリ名にglobを使用すると、ポイントが得られ、os.listdir()反復するときに最大で1つの結果がメモリに保持されます。ただしsomepath/*.txt、メモリ内の1つのディレクトリにあるすべてのファイル名を読み取ってから、そのリストを一致するものだけに減らす必要があります。
MartijnPieters

そうです、それはそれほど重要ではありませんが、在庫のCPythonですglob.glob(x) = list(glob.iglob(x))。オーバーヘッドはそれほど多くありませんが、それでも知っておくとよいでしょう。
ユージーンパンコフ2014年

これは2回繰り返されませんか?1回目はファイルを調べてリストを取得し、2回目はリスト自体を調べますか?もしそうなら、1回の反復でそれを行うことは不可能ですか?
Ridhuvarshan

6

ゲームの後半ですが、代わりにPythonfilterglob:の結果に適用することもできます。

files = glob.iglob('your_path_here')
files_i_care_about = filter(lambda x: not x.startswith("eph"), files)

またはラムダを適切な正規表現検索などに置き換えます。

編集:フルパスを使用している場合startswithは機能しないため、正規表現が必要になることに気づきました

In [10]: a
Out[10]: ['/some/path/foo', 'some/path/bar', 'some/path/eph_thing']

In [11]: filter(lambda x: not re.search('/eph', x), a)
Out[11]: ['/some/path/foo', 'some/path/bar']

5

フォルダ内のすべてのファイルを繰り返し処理しながら、特定のファイルをスキップするのはどうですか?以下のコードは、「eph」で始まるすべてのExcelファイルをスキップします

import glob
import re
for file in glob.glob('*.xlsx'):
    if re.match('eph.*\.xlsx',file):
        continue
    else:
        #do your stuff here
        print(file)

このようにして、より複雑な正規表現パターンを使用して、フォルダー内の特定のファイルセットを含めたり除外したりできます。


5

と比較してglob、私はお勧めしますpathlib、フィルター1つのパターンは非常に簡単です。

from pathlib import Path

p = Path(YOUR_PATH)
filtered = [x for x in p.glob("**/*") if not x.name.startswith("eph")]

さらに複雑なパターンをフィルタリングする場合は、次のように、それを行う関数を定義できます。

def not_in_pattern(x):
    return (not x.name.startswith("eph")) and not x.name.startswith("epi")


filtered = [x for x in p.glob("**/*") if not_in_pattern(x)]

そのコードを使用すると、で始まるephまたはで始まるすべてのファイルをフィルタリングできますepi


4

より一般的には、一部のシェル正規表現に準拠していないファイルを除外するには、モジュールを使用できますfnmatch

import fnmatch

file_list = glob('somepath')    
for ind, ii in enumerate(file_list):
    if not fnmatch.fnmatch(ii, 'bash_regexp_with_exclude'):
        file_list.pop(ind)

上記は、最初に指定されたパスからリストを生成し、次に、目的の制約で正規表現を満たさないファイルをポップアウトします。


0

受け入れられた回答で述べられているように、globでパターンを除外することはできないため、以下はglobの結果をフィルタリングする方法です。

受け入れられた答えはおそらく物事を行うための最良のpythonic方法ですが、リスト内包表記が少し醜く見え、とにかく(私がしたように)コードを最大限にnumpythonicにしたい場合は、これを行うことができます(ただし、これはおそらく効率が悪いことに注意してください)リスト内包法より):

import glob

data_files = glob.glob("path_to_files/*.fits")

light_files = np.setdiff1d( data_files, glob.glob("*BIAS*"))
light_files = np.setdiff1d(light_files, glob.glob("*FLAT*"))

(私の場合、いくつかの画像フレーム、バイアスフレーム、フラットフレームがすべて1つのディレクトリにあり、画像フレームが必要でした)


0

文字の位置が重要でない場合、つまり、マニフェストファイル(見つかった場所_)をglobおよびre-正規表現操作で除外する場合は、次を使用できます。

import glob
import re
for file in glob.glob('*.txt'):
    if re.match(r'.*\_.*', file):
        continue
    else:
        print(file)

または、よりエレガントな方法で- list comprehension

filtered = [f for f in glob.glob('*.txt') if not re.match(r'.*\_.*', f)]

for mach in filtered:
    print(mach)

-1

以下の方法を使用できます。

# Get all the files
allFiles = glob.glob("*")
# Files starting with eph
ephFiles = glob.glob("eph*")
# Files which doesnt start with eph
noephFiles = []
for file in allFiles:
    if file not in ephFiles:
        noephFiles.append(file)
# noepchFiles has all the file which doesnt start with eph.

Thank you.  
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.