나는 C ++ / Obj-C 배경을 가지고 있으며 파이썬을 발견하고 있습니다 (약 1 시간 동안 작성했습니다). 폴더 구조에서 텍스트 파일의 내용을 재귀 적으로 읽는 스크립트를 작성 중입니다.
내가 가진 문제는 내가 작성한 코드가 한 폴더 깊이에서만 작동한다는 것입니다. 코드에서 이유를 볼 수 있습니다 ( #hardcoded path
), 파이썬에 대한 나의 경험이 새로운 것이므로 파이썬으로 어떻게 나아갈 수 있는지 모르겠습니다.
파이썬 코드 :
import os
import sys
rootdir = sys.argv[1]
for root, subFolders, files in os.walk(rootdir):
for folder in subFolders:
outfileName = rootdir + "/" + folder + "/py-outfile.txt" # hardcoded path
folderOut = open( outfileName, 'w' )
print "outfileName is " + outfileName
for file in files:
filePath = rootdir + '/' + file
f = open( filePath, 'r' )
toWrite = f.read()
print "Writing '" + toWrite + "' to" + filePath
folderOut.write( toWrite )
f.close()
folderOut.close()
답변
다음의 세 가지 반환 값을 이해해야합니다 os.walk
.
for root, subdirs, files in os.walk(rootdir):
다음과 같은 의미가 있습니다.
root
: “통과”되는 현재 경로subdirs
:root
디렉토리 유형의 파일files
: 디렉토리 이외의 유형의 파일에root
있거나없는 파일subdirs
그리고 os.path.join
슬래시로 연결 하는 대신 사용하십시오 ! 문제는 filePath = rootdir + '/' + file
최상위 폴더 대신 현재 “걷는”폴더를 연결해야한다는 것입니다. 반드시이어야합니다 filePath = os.path.join(root, file)
. BTW “파일”은 내장되어 있으므로 일반적으로 변수 이름으로 사용하지 않습니다.
또 다른 문제는 다음과 같은 루프입니다.
import os
import sys
walk_dir = sys.argv[1]
print('walk_dir = ' + walk_dir)
# If your current working directory may change during script execution, it's recommended to
# immediately convert program arguments to an absolute path. Then the variable root below will
# be an absolute path as well. Example:
# walk_dir = os.path.abspath(walk_dir)
print('walk_dir (absolute) = ' + os.path.abspath(walk_dir))
for root, subdirs, files in os.walk(walk_dir):
print('--\nroot = ' + root)
list_file_path = os.path.join(root, 'my-directory-list.txt')
print('list_file_path = ' + list_file_path)
with open(list_file_path, 'wb') as list_file:
for subdir in subdirs:
print('\t- subdirectory ' + subdir)
for filename in files:
file_path = os.path.join(root, filename)
print('\t- file %s (full path: %s)' % (filename, file_path))
with open(file_path, 'rb') as f:
f_content = f.read()
list_file.write(('The file %s contains:\n' % filename).encode('utf-8'))
list_file.write(f_content)
list_file.write(b'\n')
당신이 모르는 경우, with
파일에 대한 설명은 속기입니다.
with open('filename', 'rb') as f:
dosomething()
# is effectively the same as
f = open('filename', 'rb')
try:
dosomething()
finally:
f.close()
답변
Python 3.5 이상을 사용하는 경우 한 줄로 수행 할 수 있습니다.
import glob
for filename in glob.iglob(root_dir + '**/*.txt', recursive=True):
print(filename)
설명서에 언급 된 바와 같이
재귀가 true 인 경우 패턴 ‘**’은 모든 파일 및 0 개 이상의 디렉토리 및 하위 디렉토리와 일치합니다.
모든 파일을 원한다면
import glob
for filename in glob.iglob(root_dir + '**/*', recursive=True):
print(filename)
답변
Dave Webb에 동의 os.walk
하면 트리의 각 디렉토리에 대한 항목이 생성됩니다. 사실, 당신은 신경 쓰지 않아도됩니다 subFolders
.
다음과 같은 코드가 작동합니다.
import os
import sys
rootdir = sys.argv[1]
for folder, subs, files in os.walk(rootdir):
with open(os.path.join(folder, 'python-outfile.txt'), 'w') as dest:
for filename in files:
with open(os.path.join(folder, filename), 'r') as src:
dest.write(src.read())
답변
TL; DR :find -type f
현재 폴더를 포함하여 아래의 모든 폴더에있는 모든 파일을 처리 하는 것과 같습니다 .
for currentpath, folders, files in os.walk('.'):
for file in files:
print(os.path.join(currentpath, file))
다른 답변에서 이미 언급했듯이 os.walk()
그 대답이 있지만 더 잘 설명 할 수 있습니다. 아주 간단합니다! 이 트리를 살펴 보겠습니다.
docs/
└── doc1.odt
pics/
todo.txt
이 코드로 :
for currentpath, folders, files in os.walk('.'):
print(currentpath)
는 currentpath
그것을보고있는 현재 폴더입니다. 출력됩니다 :
.
./docs
./pics
따라서 세 개의 폴더가 있기 때문에 세 번 반복 됩니다. 현재 폴더 docs
, 및 pics
. 모든 루프에서는 변수 채우기 folders
및 files
모든 폴더와 파일을. 그들에게 보여 주자 :
for currentpath, folders, files in os.walk('.'):
print(currentpath, folders, files)
이것은 우리에게 보여줍니다 :
# currentpath folders files
. ['pics', 'docs'] ['todo.txt']
./pics [] []
./docs [] ['doc1.odt']
첫 번째 줄에서 우리는 우리가 folder에 .
있고, 그것은 두 개의 폴더를 포함 pics
하고 docs
, 하나의 파일이 있다는 것을 알 수 있습니다 todo.txt
. 보시다시피 폴더는 자동으로 되풀이되고 하위 폴더의 파일 만 제공하기 때문에 해당 폴더로 되풀이하기 위해 아무 것도하지 않아도됩니다. 그리고 그 하위 폴더는 (이 예제에는 없지만)
모든 파일을 반복하고 싶다면 다음과 find -type f
같습니다.
for currentpath, folders, files in os.walk('.'):
for file in files:
print(os.path.join(currentpath, file))
이 결과는 다음과 같습니다.
./todo.txt
./docs/doc1.odt
답변
pathlib
라이브러리 파일 작업을위한 정말 좋은 것입니다. 이렇게 Path
객체 에 재귀 적 glob을 수행 할 수 있습니다 .
from pathlib import Path
for elem in Path('/path/to/my/files').rglob('*.*'):
print(elem)
답변
주어진 dir 아래의 모든 경로 목록을 원한다면 ( find .
쉘 과 같이 ) :
files = [
os.path.join(parent, name)
for (parent, subdirs, files) in os.walk(YOUR_DIRECTORY)
for name in files + subdirs
]
기본 디렉토리 아래에 파일의 전체 경로 만 포함 시키려면 생략하십시오 + subdirs
.
답변
import glob
import os
root_dir = <root_dir_here>
for filename in glob.iglob(root_dir + '**/**', recursive=True):
if os.path.isfile(filename):
with open(filename,'r') as file:
print(file.read())
**/**
를 포함하여 모든 파일을 재귀 적으로 가져 오는 데 사용됩니다 directory
.
if os.path.isfile(filename)
filename
변수가 file
또는인지 확인하는 데 사용되며 directory
파일 인 경우 해당 파일을 읽을 수 있습니다. 여기에 파일을 인쇄하고 있습니다.