glob 제외 패턴


답변:


152

glob의 패턴 규칙은 정규식이 아닙니다. 대신 표준 Unix 경로 확장 규칙을 따릅니다. 특수 문자는 몇 개뿐입니다. 두 개의 서로 다른 와일드 카드 및 문자 범위가 [from glob ] 에서 지원됩니다 .

따라서 패턴이있는 일부 파일을 제외 할 수 있습니다.
예를 들어 _glob으로 매니페스트 파일 (로 시작하는 파일)을 제외 하려면 다음을 사용할 수 있습니다.

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

10
이 공식 문서에 있어야합니다, 누군가가이 추가하십시오 docs.python.org/3.5/library/glob.html#glob.glob
비탈리 Zdanevich

7
glob 패턴은 OP :로 시작 eph하지만 다른 것으로 시작할 수있는 파일 만 제외하기 위해 설정된 요구 사항을 직접 채울 수는 없습니다 . 예를 들어로 [!e][!p][!h]시작하는 파일을 필터링합니다 eee.
Martijn Pieters

60

세트를 공제 할 수 있습니다.

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

4
정말 흥미로운 솔루션입니다! 그러나 내 경우는 두 번 읽는 데 매우 느릴 것입니다. 또한 네트워크 디렉토리에서 폴더의 내용이 크면 다시 느려질 것입니다. 그러나 어쨌든 정말 편리합니다.
Anastasios Andronidis 2014

파일 시스템을 캐시해야 귀하의 운영 체제 : 그래서 그렇게 나쁘지 요청
neutrinus

'목록'과 '목록': - 지원되지 않는 피연산자 유형 (들)에 대한이에게 자신을 시도, 난 그냥 형식 오류 있어요
톰 버스비

1
세트로 변환 시도 @TomBusby : set(glob("*")) - set(glob("eph*")) (말과 통지 * "엡 *")
Jaszczur

2
참고로 glob은 집합이 아닌 목록을 반환하지만 이러한 종류의 작업은 집합에서만 작동하므로 중성미자 가이를 캐스팅하는 이유 입니다. 목록으로 유지해야하는 경우 전체 작업을 캐스트로 래핑하면됩니다.list(set(glob("*")) - set(glob("eph")))
Nathan Smith

48

glob함수로 패턴을 제외 할 수 없으며 glob은 포함 패턴 만 허용합니다 . 글 로빙 구문 은 매우 제한적입니다 ( [!..]문자 클래스 조차도 문자 와 일치 해야 하므로 클래스에없는 모든 문자에 대한 포함 패턴 입니다).

자체 필터링을 수행해야합니다. 목록 이해는 일반적으로 여기에서 잘 작동합니다.

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

3
사용 iglob메모리에 전체 목록을 저장 방지하기 위해 여기
유진 판 코프

3
@Hardex : 내부적으로, 어쨌든iglob 목록을 생성합니다 . 당신이 할 일은 필터를 느리게 평가하는 것입니다. 메모리 사용량을 줄이는 데 도움이되지 않습니다.
Martijn Pieters

@Hardex : 디렉토리 이름에 glob을 사용하면 포인트가 생기고 os.listdir()반복 할 때 최대 하나의 결과가 메모리에 보관됩니다. 그러나 somepath/*.txt메모리의 한 디렉토리에있는 모든 파일 이름을 읽은 다음 해당 목록을 일치하는 파일로만 줄여야합니다.
Martijn Pieters

당신 말이 맞아, 그것은 중요하지,하지만 재고의 CPython에서 glob.glob(x) = list(glob.iglob(x)). 오버 헤드가 많지는 않지만 알아두면 좋습니다.
Eugene Pankov 2014 년

두 번 반복되지 않습니까?. 한 번 파일을 통해 목록을 얻고 두 번째는 목록 자체를 통해? 그렇다면 한 번의 반복으로 수행 할 수 없습니까?
Ridhuvarshan 2018

6

게임이 늦었지만 filter결과에 파이썬 을 적용 할 수도 있습니다 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']

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필터, 하나 개의 패턴은 매우 간단합니다.

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

보다 일반적으로 일부 쉘 정규식을 준수하지 않는 파일을 제외하려면 module을 사용할 수 있습니다 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 결과를 필터링하는 방법입니다.

받아 들여지는 대답은 아마도 일을하는 가장 좋은 비단뱀적인 방법 일 것입니다. 그러나 목록 이해가 약간 추악 해 보이고 어쨌든 (내가 한 것처럼) 코드를 최대한 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*"))

(제 경우에는 일부 이미지 프레임, 바이어스 프레임 및 플랫 프레임이 모두 하나의 디렉토리에 있었고 이미지 프레임 만 원했습니다)


0

문자의 위치가있는 경우 없는 중요한, 즉 (가 발견 된 곳 매니페스트 파일을 제외하는, 예를 들면 _)와 globre- 정규 표현식 작업을 , 당신은 사용할 수 있습니다 :

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.