Python에서 확장자가 .txt 인 디렉토리의 모든 파일 찾기


1043

.txt파이썬 에서 확장자 가 있는 디렉토리의 모든 파일을 어떻게 찾을 수 있습니까?

답변:


2354

당신은 사용할 수 있습니다 glob:

import glob, os
os.chdir("/mydir")
for file in glob.glob("*.txt"):
    print(file)

또는 간단히 os.listdir:

import os
for file in os.listdir("/mydir"):
    if file.endswith(".txt"):
        print(os.path.join("/mydir", file))

또는 디렉토리를 탐색하려면 os.walk다음을 사용하십시오 .

import os
for root, dirs, files in os.walk("/mydir"):
    for file in files:
        if file.endswith(".txt"):
             print(os.path.join(root, file))

11
솔루션 # 2를 사용하여 해당 정보로 파일 또는 목록을 어떻게 작성 하시겠습니까?
멀린

72
@ ghostdog74 : 내 의견 으로는 변수에있는 것이 단일 파일 이름이기 때문에 쓰기 for file in f보다 더 적절할 것이라고 생각합니다 for files in f. 더 좋은 점은을 변경하는 것 ffiles다음 루프에 대한이 될 수 있고 for file in files.
martineau

45
@computermacgyver : 아니요 file. 예약어가 아니며 미리 정의 된 함수의 이름 일 뿐이므로 고유 코드에서 변수 이름으로 사용할 수 있습니다. 일반적으로 그러한 충돌을 피해야한다는 것은 사실이지만, 그것을 사용해야 file할 필요가 거의 없기 때문에 특별한 경우입니다. 따라서 종종 지침의 예외로 간주됩니다. 그렇게하지 않으려면 PEP8은 이러한 이름에 단일 밑줄을 추가하는 것이 좋습니다. 즉 file_, 동의해야 할 내용은 여전히 ​​읽을 수 있습니다.
martineau

9
고마워, 마 티노, 당신 말이 맞아 나는 결론에 너무 빨리 뛰어 들었다.
computermacgyver

40
# 2에 더 파이썬 방법이 될 수 있는 파일 [os.listdir F에 대한 F ( '/ MYDIR') f.endswith 경우 ( 'TXT.')]
오즈

247

glob을 사용하십시오 .

>>> import glob
>>> glob.glob('./*.txt')
['./outline.txt', './pip-log.txt', './test.txt', './testingvim.txt']

이 작업은 쉬울뿐만 아니라 대소 문자를 구분하지 않습니다. (적어도, 그것은 Windows에 있어야합니다. 다른 OS에 대해서는 잘 모르겠습니다.)
Jon Coombs

35
파이썬이 3.5 미만인 경우 glob파일을 재귀 적으로 찾을 수 없다는 점에 유의하십시오 . 자세한 정보
qun

가장 좋은 부분은 당신이 * .txt 인 정규 표현식 테스트를 사용할 수 있습니다
알렉스 Punnen

@JonCoombs nope. 적어도 리눅스에서는 그렇지 않습니다.
Karuhanga

157

그와 같은 일이 일을해야합니다

for root, dirs, files in os.walk(directory):
    for file in files:
        if file.endswith('.txt'):
            print file

73
root, dirs, files대신 변수 이름을 지정하려면 +1 입니다 r, d, f. 훨씬 더 읽기 쉽습니다.
Clément

27
대소 문자를 구분하므로 (.TXT 또는 .Txt와 일치하지 않음) file.lower (). endswith ( '. txt') 인 경우 다음과 같이하십시오.
Jon Coombs

1
귀하의 답변은 하위 디렉토리를 처리합니다.
Sam Liao

117

이와 같은 것이 효과가 있습니다.

>>> import os
>>> path = '/usr/share/cups/charmaps'
>>> text_files = [f for f in os.listdir(path) if f.endswith('.txt')]
>>> text_files
['euc-cn.txt', 'euc-jp.txt', 'euc-kr.txt', 'euc-tw.txt', ... 'windows-950.txt']

text_files의 경로를 어떻게 저장합니까? [ 'path / euc-cn.txt', ... 'path / windows-950.txt']
IceQueeny

5
os.path.join각 요소에 사용할 수 있습니다 text_files. 같은 것일 수 있습니다 text_files = [os.path.join(path, f) for f in os.listdir(path) if f.endswith('.txt')].
세스

55

당신은 단순히 pathlibs 1을 사용할 수 있습니다 :glob

import pathlib

list(pathlib.Path('your_directory').glob('*.txt'))

또는 루프에서 :

for txt_file in pathlib.Path('your_directory').glob('*.txt'):
    # do something with "txt_file"

재귀를 원한다면 사용할 수 있습니다. .glob('**/*.txt)


1pathlib 모듈 파이썬 3.4 표준 라이브러리에 포함시켰다. 그러나 당신은 오래된 파이썬 버전 (즉, 사용에 해당 모듈의-포트를 다시 설치할 수 있습니다 conda또는 pip:) pathlibpathlib2.


**/*.txt이전 파이썬 버전에서는 지원되지 않으므로 다음과 같이 해결했습니다. foundfiles= subprocess.check_output("ls **/*.txt", shell=True) for foundfile in foundfiles.splitlines(): print foundfile
Roman

1
@Roman 예, 할 pathlib수있는 일에 대한 쇼케이스였으며 이미 Python 버전 요구 사항을 포함 시켰습니다. :) 그러나 귀하의 접근법이 아직 게시되지 않았다면 다른 답변으로 추가하지 않는 이유는 무엇입니까?
MSeifert

1
예, 답변을 게시하면 더 나은 형식 지정 가능성을 알 수 있습니다. 나는 이것이 더 적절한 장소라고 생각하기 때문에 거기에서 postet 합니다.
로마

5
rglob항목을 재귀 적으로 찾으려면 사용할 수도 있습니다 . 예.rglob('*.txt')
Bram Vanroy 2016 년

40
import os

path = 'mypath/path' 
files = os.listdir(path)

files_txt = [i for i in files if i.endswith('.txt')]

29

나는 os.walk ()를 좋아 한다 :

import os

for root, dirs, files in os.walk(dir):
    for f in files:
        if os.path.splitext(f)[1] == '.txt':
            fullpath = os.path.join(root, f)
            print(fullpath)

또는 발전기로 :

import os

fileiter = (os.path.join(root, f)
    for root, _, files in os.walk(dir)
    for f in files)
txtfileiter = (f for f in fileiter if os.path.splitext(f)[1] == '.txt')
for txt in txtfileiter:
    print(txt)

28

약간 다른 결과를 생성하는 동일한 버전이 더 있습니다.

glob.iglob ()

import glob
for f in glob.iglob("/mydir/*/*.txt"): # generator, search immediate subdirectories 
    print f

glob.glob1 ()

print glob.glob1("/mydir", "*.tx?")  # literal_directory, basename_pattern

fnmatch.filter ()

import fnmatch, os
print fnmatch.filter(os.listdir("/mydir"), "*.tx?") # include dot-files

3
궁금한 점 은 파이썬 설명서에 나와 있지 않은 모듈 glob1()의 도우미 함수입니다 glob. 소스 파일에서 수행하는 작업을 설명하는 인라인 주석이 있습니다 (참조) .../Lib/glob.py.
martineau

1
@martineau : glob.glob1()공개는 아니지만 Python 2.4-2.7; 3.0-3.2에서 사용할 수 있습니다. 파이 jython github.com/zed/test_glob1
jfs

1
감사합니다. 모듈에서 문서화되지 않은 개인 함수를 사용할지 여부를 결정할 때 유용한 추가 정보입니다. ;-) 여기 조금 더 있습니다. Python 2.7 버전은 길이가 12 줄에 불과하며 glob모듈 에서 쉽게 추출 할 수있는 것처럼 보입니다 .
martineau

21

path.py는 또 다른 대안입니다 : https://github.com/jaraco/path.py

from path import path
p = path('/path/to/the/directory')
for f in p.files(pattern='*.txt'):
    print f

멋지다, 그것은 또한 정규 표현식 패턴을 받아들입니다. 나는 for f in p.walk(pattern='*.txt')모든 하위 폴더를 사용하고 있습니다
Kostanos

1
나중에 pathlib도 있습니다. 다음과 같은 작업을 수행 할 수 있습니다. list(p.glob('**/*.py'))
user2233949

15

파이썬 v3.5 +

재귀 함수에서 os.scandir을 사용하는 빠른 방법. 폴더 및 하위 폴더에서 지정된 확장자를 가진 모든 파일을 검색합니다.

import os

def findFilesInFolder(path, pathList, extension, subFolders = True):
    """  Recursive function to find all files of an extension type in a folder (and optionally in all subfolders too)

    path:        Base directory to find files
    pathList:    A list that stores all paths
    extension:   File extension to find
    subFolders:  Bool.  If True, find files in all subfolders under path. If False, only searches files in the specified folder
    """

    try:   # Trapping a OSError:  File permissions problem I believe
        for entry in os.scandir(path):
            if entry.is_file() and entry.path.endswith(extension):
                pathList.append(entry.path)
            elif entry.is_dir() and subFolders:   # if its a directory, then repeat process as a nested function
                pathList = findFilesInFolder(entry.path, pathList, extension, subFolders)
    except OSError:
        print('Cannot access ' + path +'. Probably a permissions error')

    return pathList

dir_name = r'J:\myDirectory'
extension = ".txt"

pathList = []
pathList = findFilesInFolder(dir_name, pathList, extension, True)

2019 년 4 월 업데이트

10,000s 파일이 포함 된 디렉토리를 검색하는 경우 목록에 추가하는 것이 비효율적입니다. 결과를 '수확'하는 것이 더 나은 솔루션입니다. 또한 출력을 Pandas Dataframe으로 변환하는 기능도 포함했습니다.

import os
import re
import pandas as pd
import numpy as np


def findFilesInFolderYield(path,  extension, containsTxt='', subFolders = True, excludeText = ''):
    """  Recursive function to find all files of an extension type in a folder (and optionally in all subfolders too)

    path:               Base directory to find files
    extension:          File extension to find.  e.g. 'txt'.  Regular expression. Or  'ls\d' to match ls1, ls2, ls3 etc
    containsTxt:        List of Strings, only finds file if it contains this text.  Ignore if '' (or blank)
    subFolders:         Bool.  If True, find files in all subfolders under path. If False, only searches files in the specified folder
    excludeText:        Text string.  Ignore if ''. Will exclude if text string is in path.
    """
    if type(containsTxt) == str: # if a string and not in a list
        containsTxt = [containsTxt]

    myregexobj = re.compile('\.' + extension + '$')    # Makes sure the file extension is at the end and is preceded by a .

    try:   # Trapping a OSError or FileNotFoundError:  File permissions problem I believe
        for entry in os.scandir(path):
            if entry.is_file() and myregexobj.search(entry.path): # 

                bools = [True for txt in containsTxt if txt in entry.path and (excludeText == '' or excludeText not in entry.path)]

                if len(bools)== len(containsTxt):
                    yield entry.stat().st_size, entry.stat().st_atime_ns, entry.stat().st_mtime_ns, entry.stat().st_ctime_ns, entry.path

            elif entry.is_dir() and subFolders:   # if its a directory, then repeat process as a nested function
                yield from findFilesInFolderYield(entry.path,  extension, containsTxt, subFolders)
    except OSError as ose:
        print('Cannot access ' + path +'. Probably a permissions error ', ose)
    except FileNotFoundError as fnf:
        print(path +' not found ', fnf)

def findFilesInFolderYieldandGetDf(path,  extension, containsTxt, subFolders = True, excludeText = ''):
    """  Converts returned data from findFilesInFolderYield and creates and Pandas Dataframe.
    Recursive function to find all files of an extension type in a folder (and optionally in all subfolders too)

    path:               Base directory to find files
    extension:          File extension to find.  e.g. 'txt'.  Regular expression. Or  'ls\d' to match ls1, ls2, ls3 etc
    containsTxt:        List of Strings, only finds file if it contains this text.  Ignore if '' (or blank)
    subFolders:         Bool.  If True, find files in all subfolders under path. If False, only searches files in the specified folder
    excludeText:        Text string.  Ignore if ''. Will exclude if text string is in path.
    """

    fileSizes, accessTimes, modificationTimes, creationTimes , paths  = zip(*findFilesInFolderYield(path,  extension, containsTxt, subFolders))
    df = pd.DataFrame({
            'FLS_File_Size':fileSizes,
            'FLS_File_Access_Date':accessTimes,
            'FLS_File_Modification_Date':np.array(modificationTimes).astype('timedelta64[ns]'),
            'FLS_File_Creation_Date':creationTimes,
            'FLS_File_PathName':paths,
                  })

    df['FLS_File_Modification_Date'] = pd.to_datetime(df['FLS_File_Modification_Date'],infer_datetime_format=True)
    df['FLS_File_Creation_Date'] = pd.to_datetime(df['FLS_File_Creation_Date'],infer_datetime_format=True)
    df['FLS_File_Access_Date'] = pd.to_datetime(df['FLS_File_Access_Date'],infer_datetime_format=True)

    return df

ext =   'txt'  # regular expression 
containsTxt=[]
path = 'C:\myFolder'
df = findFilesInFolderYieldandGetDf(path,  ext, containsTxt, subFolders = True)

14

파이썬은 이것을하기위한 모든 도구를 가지고 있습니다 :

import os

the_dir = 'the_dir_that_want_to_search_in'
all_txt_files = filter(lambda x: x.endswith('.txt'), os.listdir(the_dir))

1
all_txt_files를 목록으로 만들려면 :all_txt_files = list(filter(lambda x: x.endswith('.txt'), os.listdir(the_dir)))
Ena

12

'dataPath'폴더 내의 모든 '.txt'파일 이름을 Python 방식으로 목록으로 가져 오려면 다음을 수행하십시오.

from os import listdir
from os.path import isfile, join
path = "/dataPath/"
onlyTxtFiles = [f for f in listdir(path) if isfile(join(path, f)) and  f.endswith(".txt")]
print onlyTxtFiles

12

이것을 시도하면 모든 파일을 재귀 적으로 찾을 수 있습니다.

import glob, os
os.chdir("H:\\wallpaper")# use whatever directory you want

#double\\ no single \

for file in glob.glob("**/*.txt", recursive = True):
    print(file)

재귀 버전이 아님 (더블 스타 :) **. 파이썬 3에서만 사용할 수 있습니다. 내가 싫어하는 것은 chdir부분입니다. 그럴 필요가 없습니다.
Jean-François Fabre

2
예를 들어, os 라이브러리를 사용하여 경로를 결합한 filepath = os.path.join('wallpaper')다음로 사용 glob.glob(filepath+"**/*.psd", recursive = True)하여 동일한 결과를 얻을 수 있습니다.
Mitalee Rao 5

8
import os
import sys 

if len(sys.argv)==2:
    print('no params')
    sys.exit(1)

dir = sys.argv[1]
mask= sys.argv[2]

files = os.listdir(dir); 

res = filter(lambda x: x.endswith(mask), files); 

print res

8

테스트 (Python 3.6.4, W7x64)를 수행하여 특정 확장자를 가진 파일의 전체 파일 경로 목록을 가져 오기 위해 하위 디렉토리가 아닌 하나의 폴더에 가장 빠른 솔루션을 확인했습니다.

요약하자면,이 작업 os.listdir()이 가장 빠르며 다음 최고 속도보다 1.7 배 빠릅니다 os.walk()(중단됨!), 2.7 pathlib배 빠름, 3.2 배 빠름 os.scandir()및 3.3 배 빠름 glob.
재귀 적 결과가 필요할 때 이러한 결과가 변경 될 수 있습니다. 아래의 방법 중 하나를 복사 / 붙여 넣는 경우 .lower ()를 추가하십시오. 그렇지 않으면 .ext를 검색 할 때 .EXT를 찾을 수 없습니다.

import os
import pathlib
import timeit
import glob

def a():
    path = pathlib.Path().cwd()
    list_sqlite_files = [str(f) for f in path.glob("*.sqlite")]

def b(): 
    path = os.getcwd()
    list_sqlite_files = [f.path for f in os.scandir(path) if os.path.splitext(f)[1] == ".sqlite"]

def c():
    path = os.getcwd()
    list_sqlite_files = [os.path.join(path, f) for f in os.listdir(path) if f.endswith(".sqlite")]

def d():
    path = os.getcwd()
    os.chdir(path)
    list_sqlite_files = [os.path.join(path, f) for f in glob.glob("*.sqlite")]

def e():
    path = os.getcwd()
    list_sqlite_files = [os.path.join(path, f) for f in glob.glob1(str(path), "*.sqlite")]

def f():
    path = os.getcwd()
    list_sqlite_files = []
    for root, dirs, files in os.walk(path):
        for file in files:
            if file.endswith(".sqlite"):
                list_sqlite_files.append( os.path.join(root, file) )
        break



print(timeit.timeit(a, number=1000))
print(timeit.timeit(b, number=1000))
print(timeit.timeit(c, number=1000))
print(timeit.timeit(d, number=1000))
print(timeit.timeit(e, number=1000))
print(timeit.timeit(f, number=1000))

결과 :

# Python 3.6.4
0.431
0.515
0.161
0.548
0.537
0.274

파이썬 3.6.5 문서는 다음과 같이 기술하고 있습니다. os.scandir () 함수는 파일 속성 정보와 함께 디렉토리 엔트리를 반환하여 많은 일반적인 사용 사례에서 os.listdir ()보다 나은 성능을 제공합니다.
빌 Oldroyd

이 테스트에서 얼마나 많은 파일을 사용 했습니까? 숫자를 올리거나 내릴 때 어떻게 비교합니까?
N4ppeL

5

이 코드는 내 인생을 더 단순하게 만듭니다.

import os
fnames = ([file for root, dirs, files in os.walk(dir)
    for file in files
    if file.endswith('.txt') #or file.endswith('.png') or file.endswith('.pdf')
    ])
for fname in fnames: print(fname)


5

동일한 디렉토리에있는 "data"라는 폴더에서 ".txt"파일 이름 배열을 얻으려면 일반적으로이 간단한 코드 줄을 사용합니다.

import os
fileNames = [fileName for fileName in os.listdir("data") if fileName.endswith(".txt")]

3

fnmatch 와 위 방법 을 사용하는 것이 좋습니다 . 이 방법으로 다음 중 하나를 찾을 수 있습니다.

  1. 이름. txt ;
  2. 이름. TXT ;
  3. 이름. Txt

.

import fnmatch
import os

    for file in os.listdir("/Users/Johnny/Desktop/MyTXTfolder"):
        if fnmatch.fnmatch(file.upper(), '*.TXT'):
            print(file)

3

여기에 하나 extend()

types = ('*.jpg', '*.png')
images_list = []
for files in types:
    images_list.extend(glob.glob(os.path.join(path, files)))

.txt:) 와 함께 사용 불가
Efreeto

2

하위 디렉토리가있는 기능적 솔루션 :

from fnmatch import filter
from functools import partial
from itertools import chain
from os import path, walk

print(*chain(*(map(partial(path.join, root), filter(filenames, "*.txt")) for root, _, filenames in walk("mydir"))))

15
이 코드를 장기적으로 유지하고 싶습니까?
Simeon Visser

2

폴더에 많은 파일이 있거나 메모리가 제한적인 경우 생성기를 사용하는 것이 좋습니다.

def yield_files_with_extensions(folder_path, file_extension):
   for _, _, files in os.walk(folder_path):
       for file in files:
           if file.endswith(file_extension):
               yield file

옵션 A : 반복

for f in yield_files_with_extensions('.', '.txt'): 
    print(f)

옵션 B : 모두 가져 오기

files = [f for f in yield_files_with_extensions('.', '.txt')]

2

고스트 독과 비슷한 복사 가능 솔루션 :

def get_all_filepaths(root_path, ext):
    """
    Search all files which have a given extension within root_path.

    This ignores the case of the extension and searches subdirectories, too.

    Parameters
    ----------
    root_path : str
    ext : str

    Returns
    -------
    list of str

    Examples
    --------
    >>> get_all_filepaths('/run', '.lock')
    ['/run/unattended-upgrades.lock',
     '/run/mlocate.daily.lock',
     '/run/xtables.lock',
     '/run/mysqld/mysqld.sock.lock',
     '/run/postgresql/.s.PGSQL.5432.lock',
     '/run/network/.ifstate.lock',
     '/run/lock/asound.state.lock']
    """
    import os
    all_files = []
    for root, dirs, files in os.walk(root_path):
        for filename in files:
            if filename.lower().endswith(ext):
                all_files.append(os.path.join(root, filename))
    return all_files

1

Python OS 모듈을 사용 하여 특정 확장자를 가진 파일을 찾으십시오.

간단한 예는 다음과 같습니다.

import os

# This is the path where you want to search
path = r'd:'  

# this is extension you want to detect
extension = '.txt'   # this can be : .jpg  .png  .xls  .log .....

for root, dirs_list, files_list in os.walk(path):
    for file_name in files_list:
        if os.path.splitext(file_name)[-1] == extension:
            file_name_path = os.path.join(root, file_name)
            print file_name
            print file_name_path   # This is the full path of the filter file

0

많은 사용자가 os.walk모든 파일뿐만 아니라 모든 디렉토리와 하위 디렉토리 및 해당 파일을 포함 하는 답변 으로 답변했습니다.

import os


def files_in_dir(path, extension=''):
    """
       Generator: yields all of the files in <path> ending with
       <extension>

       \param   path       Absolute or relative path to inspect,
       \param   extension  [optional] Only yield files matching this,

       \yield              [filenames]
    """


    for _, dirs, files in os.walk(path):
        dirs[:] = []  # do not recurse directories.
        yield from [f for f in files if f.endswith(extension)]

# Example: print all the .py files in './python'
for filename in files_in_dir('./python', '*.py'):
    print("-", filename)

또는 발전기가 필요없는 곳의 경우 :

path, ext = "./python", ext = ".py"
for _, _, dirfiles in os.walk(path):
    matches = (f for f in dirfiles if f.endswith(ext))
    break

for filename in matches:
    print("-", filename)

다른 것에 일치 항목을 사용하려는 경우 생성기 표현식이 아닌 목록으로 만들 수 있습니다.

    matches = [f for f in dirfiles if f.endswith(ext)]

0

for루프 를 사용하여 간단한 방법 :

import os

dir = ["e","x","e"]

p = os.listdir('E:')  #path

for n in range(len(p)):
   name = p[n]
   myfile = [name[-3],name[-2],name[-1]]  #for .txt
   if myfile == dir :
      print(name)
   else:
      print("nops")

이것은 좀 더 일반화 될 수 있습니다.


확장 성을 확인하는 매우 비현실적인 방법. 안전하지 않습니다. 이름이 너무 짧으면 어떻게합니까? 왜 문자열이 아닌 문자 목록을 사용합니까?
Jean-François Fabre
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.