Ich habe ein Verzeichnis mit einer Reihe von Dateien : eee2314
, asd3442
... und eph
.
Ich möchte alle Dateien ausschließen, die eph
mit der glob
Funktion beginnen.
Wie kann ich es tun?
Ich habe ein Verzeichnis mit einer Reihe von Dateien : eee2314
, asd3442
... und eph
.
Ich möchte alle Dateien ausschließen, die eph
mit der glob
Funktion beginnen.
Wie kann ich es tun?
Antworten:
Die Musterregeln für glob sind keine regulären Ausdrücke. Stattdessen folgen sie den Standardregeln für die Unix-Pfaderweiterung. Es gibt nur wenige Sonderzeichen: Zwei verschiedene Platzhalter und Zeichenbereiche werden unterstützt [von glob ].
Sie können also einige Dateien mit Mustern ausschließen.
Um beispielsweise Manifestdateien (Dateien, die mit beginnen _
) mit glob auszuschließen , können Sie Folgendes verwenden:
files = glob.glob('files_path/[!_]*')
eph
, die mit etwas anderem beginnen, aber mit etwas anderem beginnen können. [!e][!p][!h]
filtert beispielsweise Dateien heraus, die mit beginnen eee
.
Sie können Sätze abziehen:
set(glob("*")) - set(glob("eph*"))
set(glob("*")) - set(glob("eph*"))
(und beachten Sie * am Ende von "eph *")
list(set(glob("*")) - set(glob("eph")))
Sie können Muster mit der glob
Funktion nicht ausschließen. Globs erlauben nur Einschlussmuster . Die Globbing-Syntax ist sehr begrenzt (selbst eine [!..]
Zeichenklasse muss mit einem Zeichen übereinstimmen, daher handelt es sich um ein Einschlussmuster für jedes Zeichen, das nicht zur Klasse gehört).
Sie müssen Ihre eigene Filterung durchführen. Ein Listenverständnis funktioniert hier normalerweise gut:
files = [fn for fn in glob('somepath/*.txt')
if not os.path.basename(fn).startswith('eph')]
iglob
hier, um zu vermeiden, dass die vollständige Liste im Speicher gespeichert wird
iglob
erzeugt sowieso Listen ; Alles, was Sie tun, ist, den Filter träge auszuwerten. Es wird nicht helfen, den Speicherbedarf zu verringern.
os.listdir()
Ergebnis beim Iterieren im Speicher gespeichert. Sie müssen somepath/*.txt
jedoch alle Dateinamen in einem Verzeichnis im Speicher lesen und diese Liste dann auf nur die übereinstimmenden reduzieren.
glob.glob(x) = list(glob.iglob(x))
. Nicht viel Aufwand, aber immer noch gut zu wissen.
Spät zum Spiel, aber Sie können alternativ auch einfach eine Python filter
auf das Ergebnis von glob
:
files = glob.iglob('your_path_here')
files_i_care_about = filter(lambda x: not x.startswith("eph"), files)
oder Ersetzen des Lambda durch eine entsprechende Regex-Suche usw.
EDIT: Ich habe gerade festgestellt, dass wenn Sie vollständige Pfade verwenden startswith
, dies nicht funktioniert, sodass Sie einen regulären Ausdruck benötigen
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']
Wie wäre es, wenn Sie die bestimmte Datei überspringen, während Sie alle Dateien im Ordner durchlaufen? Der folgende Code überspringt alle Excel-Dateien, die mit 'eph' beginnen.
import glob
import re
for file in glob.glob('*.xlsx'):
if re.match('eph.*\.xlsx',file):
continue
else:
#do your stuff here
print(file)
Auf diese Weise können Sie komplexere Regex-Muster verwenden, um einen bestimmten Satz von Dateien in einem Ordner einzuschließen / auszuschließen.
Vergleichen Sie mit glob
, ich empfehle pathlib
, Filter ein Muster ist sehr einfach.
from pathlib import Path
p = Path(YOUR_PATH)
filtered = [x for x in p.glob("**/*") if not x.name.startswith("eph")]
und wenn Sie komplexere Muster filtern möchten, können Sie eine Funktion definieren, um dies zu tun, genau wie:
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)]
Mit diesem Code können Sie alle Dateien filtern, die mit eph
oder beginnen epi
.
Um Dateien auszuschließen, die nicht mit einem regulären Shell-Ausdruck übereinstimmen, können Sie im Allgemeinen das folgende Modul verwenden 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)
Das Obige generiert zuerst eine Liste aus einem bestimmten Pfad und zeigt als nächstes die Dateien an, die den regulären Ausdruck nicht mit der gewünschten Einschränkung erfüllen.
Wie in der akzeptierten Antwort erwähnt, können Sie Muster mit glob nicht ausschließen. Im Folgenden finden Sie eine Methode zum Filtern Ihres Glob-Ergebnisses.
Die akzeptierte Antwort ist wahrscheinlich die beste pythonische Methode, um Dinge zu tun. Wenn Sie jedoch der Meinung sind, dass Listenverständnisse etwas hässlich aussehen und Ihren Code ohnehin maximal numpythonisch machen möchten (wie ich), können Sie dies tun (beachten Sie jedoch, dass dies wahrscheinlich weniger effizient ist als die Listenverständnismethode):
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*"))
(In meinem Fall hatte ich einige Bilderrahmen, Schrägrahmen und flache Rahmen in einem Verzeichnis und wollte nur die Bilderrahmen)
Wenn die Position des Zeichens nicht wichtig ist, z. B. um Manifestdateien (wo immer sie gefunden werden _
) mit glob
und re
- regulären Ausdrucksoperationen auszuschließen , können Sie Folgendes verwenden:
import glob
import re
for file in glob.glob('*.txt'):
if re.match(r'.*\_.*', file):
continue
else:
print(file)
Oder eleganter mit - list comprehension
filtered = [f for f in glob.glob('*.txt') if not re.match(r'.*\_.*', f)]
for mach in filtered:
print(mach)
Sie können die folgende Methode verwenden:
# 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.