Eu tenho um diretório com um monte de arquivos dentro: eee2314, asd3442... e eph.
Desejo excluir todos os arquivos que começam ephcom a globfunçã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 ephcom a globfunçã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/[!_]*')
ephmas podem começar com qualquer outra coisa. [!e][!p][!h]irá filtrar os arquivos que começam com, eeepor 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 globfunçã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')]
iglobaqui para evitar o armazenamento da lista completa na memória
iglobproduz 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/*.txttem 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 filterao 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 startswithnã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 ephou 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 globe 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.