Eu tenho um diretório com um monte de arquivos dentro: eee2314
, asd3442
... e eph
.
Desejo excluir todos os arquivos que começam eph
com a glob
função.
Como eu posso fazer isso?
Eu tenho um diretório com um monte de arquivos dentro: eee2314
, asd3442
... e eph
.
Desejo excluir todos os arquivos que começam eph
com a glob
função.
Como eu posso fazer isso?
Respostas:
As regras de padrão para glob não são expressões regulares. Em vez disso, eles seguem as regras padrão de expansão de caminho do Unix. Existem apenas alguns caracteres especiais: dois curingas diferentes e intervalos de caracteres são suportados [de glob ].
Portanto, você pode excluir alguns arquivos com padrões.
Por exemplo, para excluir arquivos de manifestos (arquivos começando com _
) com glob, você pode usar:
files = glob.glob('files_path/[!_]*')
eph
mas podem começar com qualquer outra coisa. [!e][!p][!h]
irá filtrar os arquivos que começam com, eee
por exemplo.
Você pode deduzir conjuntos:
set(glob("*")) - set(glob("eph*"))
set(glob("*")) - set(glob("eph*"))
(e observe * no final de "eph *")
list(set(glob("*")) - set(glob("eph")))
Você não pode excluir padrões com a glob
função, globs permitem apenas padrões de inclusão . A sintaxe de globbing é muito limitada (até mesmo uma [!..]
classe de caractere deve corresponder a um caractere, portanto, é um padrão de inclusão para cada caractere que não está na classe).
Você terá que fazer sua própria filtragem; uma compreensão de lista geralmente funciona bem aqui:
files = [fn for fn in glob('somepath/*.txt')
if not os.path.basename(fn).startswith('eph')]
iglob
aqui para evitar o armazenamento da lista completa na memória
iglob
produz listas de qualquer maneira ; tudo o que você faz é avaliar o filtro preguiçosamente. Isso não ajudará a reduzir o consumo de memória.
os.listdir()
resultado é mantido na memória conforme você itera. Mas somepath/*.txt
tem que ler todos os nomes de arquivo em um diretório na memória e, em seguida, reduzir essa lista para apenas aqueles que correspondem.
glob.glob(x) = list(glob.iglob(x))
,. Não é muito uma sobrecarga, mas é bom saber.
Atrasado no jogo, mas você pode, alternativamente, apenas aplicar um python filter
ao resultado de glob
:
files = glob.iglob('your_path_here')
files_i_care_about = filter(lambda x: not x.startswith("eph"), files)
ou substituindo o lambda por uma pesquisa regex apropriada, etc ...
EDIT: Acabei de perceber que se você estiver usando caminhos completos, o startswith
não funcionará, então você precisa de um regex
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']
Que tal pular um arquivo específico enquanto itera todos os arquivos na pasta! O código abaixo pularia todos os arquivos do Excel que começam com 'eph'
import glob
import re
for file in glob.glob('*.xlsx'):
if re.match('eph.*\.xlsx',file):
continue
else:
#do your stuff here
print(file)
Dessa forma, você pode usar padrões regex mais complexos para incluir / excluir um determinado conjunto de arquivos em uma pasta.
Compare com glob
, eu recomendo pathlib
, filtrar um padrão é muito simples.
from pathlib import Path
p = Path(YOUR_PATH)
filtered = [x for x in p.glob("**/*") if not x.name.startswith("eph")]
e se você quiser filtrar um padrão mais complexo, pode definir uma função para fazer isso, assim:
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)]
usar esse código, você pode filtrar todos os arquivos que começam com eph
ou começam com epi
.
De forma mais geral, para excluir arquivos que não estão em conformidade com alguma regexp de shell, você pode usar o módulo 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)
O código acima irá primeiro gerar uma lista de um determinado caminho e, em seguida, exibir os arquivos que não satisfarão a expressão regular com a restrição desejada.
Conforme mencionado pela resposta aceita, você não pode excluir padrões com glob, então o seguinte é um método para filtrar seu resultado glob.
A resposta aceita é provavelmente a melhor maneira pythônica de fazer as coisas, mas se você acha que as compreensões de lista parecem um pouco feias e quer tornar seu código numpythônico máximo de qualquer maneira (como eu fiz), então você pode fazer isso (mas note que isso é provavelmente menos eficiente do que o método de compreensão de lista):
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*"))
(No meu caso, eu tinha alguns quadros de imagem, quadros enviesados e quadros planos, todos em um diretório e queria apenas os quadros de imagem)
Se a posição do caractere não for importante, por exemplo, para excluir arquivos de manifestos (onde quer que seja encontrado _
) com glob
e re
- operações de expressão regular , você pode usar:
import glob
import re
for file in glob.glob('*.txt'):
if re.match(r'.*\_.*', file):
continue
else:
print(file)
Ou de uma forma mais elegante - list comprehension
filtered = [f for f in glob.glob('*.txt') if not re.match(r'.*\_.*', f)]
for mach in filtered:
print(mach)
Você pode usar o método abaixo:
# 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.