eee2314
、asd3442
...、eph
。の中にたくさんのファイルがあるディレクトリがあります。
私はで始まるすべてのファイル除外したいeph
とglob
機能を。
どうすればいいですか?
eee2314
、asd3442
...、eph
。の中にたくさんのファイルがあるディレクトリがあります。
私はで始まるすべてのファイル除外したいeph
とglob
機能を。
どうすればいいですか?
回答:
globのパターンルールは正規表現ではありません。代わりに、標準のUnixパス拡張ルールに従います。特殊文字はごくわずかです。2つの異なるワイルドカードと文字範囲が[ globから]サポートされています。
したがって、パターンを含むいくつかのファイルを除外できます。
たとえば_
、globでマニフェストファイル(で始まるファイル)を除外するには、次のコマンドを使用できます。
files = glob.glob('files_path/[!_]*')
eph
、それ以外のもので始めることができます。たとえば[!e][!p][!h]
で始まるファイルを除外しますeee
。
セットを差し引くことができます:
set(glob("*")) - set(glob("eph*"))
set(glob("*")) - set(glob("eph*"))
そして「eph *」の終わりに*注意してください)
glob
関数でパターンを除外することはできません。グロブは包含パターンのみを許可します。グロブ構文は非常に制限されています([!..]
文字クラスでさえ文字と一致する必要があるため、クラスに含まれないすべての文字の包含パターンです)。
独自のフィルタリングを行う必要があります。リスト内包表記は通常、ここでうまく機能します。
files = [fn for fn in glob('somepath/*.txt')
if not os.path.basename(fn).startswith('eph')]
iglob
完全なリストがメモリに保存されないようにするには、ここを使用してください
iglob
リストを生成します; フィルタを怠惰に評価するだけです。メモリフットプリントを削減するのに役立ちません。
os.listdir()
反復するときに最大で1つの結果がメモリに保持されます。ただしsomepath/*.txt
、メモリ内の1つのディレクトリにあるすべてのファイル名を読み取ってから、そのリストを一致するものだけに減らす必要があります。
glob.glob(x) = list(glob.iglob(x))
。オーバーヘッドはそれほど多くありませんが、それでも知っておくとよいでしょう。
ゲームの後半ですが、代わりにPythonfilter
をglob
:の結果に適用することもできます。
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']
と比較して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
。
より一般的には、一部のシェル正規表現に準拠していないファイルを除外するには、モジュールを使用できます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)
上記は、最初に指定されたパスからリストを生成し、次に、目的の制約で正規表現を満たさないファイルをポップアウトします。
受け入れられた回答で述べられているように、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つのディレクトリにあり、画像フレームが必要でした)
文字の位置が重要でない場合、つまり、マニフェストファイル(見つかった場所_
)を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)
以下の方法を使用できます。
# 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.