Python에서 파일 이름만 가져오기 위해 파일 목록을 어떻게 구문 분석합니까?

StackOverflow https://stackoverflow.com/questions/237699

문제

그럼 내가 Python을 사용하고 있다고 가정 해 봅시다. ftplib FTP 서버에서 로그 파일 목록을 검색합니다.목록 내의 파일 이름(마지막 열)만 가져오기 위해 해당 파일 목록을 어떻게 구문 분석합니까?예제 출력은 위의 링크를 참조하세요.

도움이 되었습니까?

해결책

Retrlines ()를 사용하는 것이 가장 좋은 아이디어는 아닐 것입니다. 왜냐하면 그것은 콘솔에 인쇄하기 때문에 그 출력에도 얻기 위해 까다로운 일을해야하기 때문입니다. 더 나은 내기는 NLST () 메소드를 사용하는 것입니다.이 방법은 원하는 것을 정확하게 반환합니다 : 파일 이름 목록.

다른 팁

이 베스트 답변

사용하고 싶을 수도 있습니다 ftp.nlst() 대신에 ftp.retrlines(). 그것은 당신이 원하는 것을 정확하게 줄 것입니다.

할 수 없다면 다음을 읽으십시오.

Sysadmin 프로세스를위한 생성기

그의 유명한 리뷰에서 시스템 프로그래머를위한 발전기 트릭, David M. Beazley는 Wuick 및 재사용 가능한 코드의 이러한 종류의 데이터 문제에 대한 답변을 위해 많은 영수증을 제공합니다.

예 :

# empty list that will receive all the log entry
log = [] 
# we pass a callback function bypass the print_line that would be called by retrlines
# we do that only because we cannot use something better than retrlines
ftp.retrlines('LIST', callback=log.append)
# we use rsplit because it more efficient in our case if we have a big file
files = (line.rsplit(None, 1)[1] for line in log)
# get you file list
files_list = list(files)

왜 목록을 즉시 생성하지 않습니까?

글쎄, 이런 식으로 수행하는 것은 많은 유연성을 제공하기 때문입니다. 파일을 전환하기 전에 파일을 필터링하기 위해 중간 생성기를 적용 할 수 있습니다. files_list : 파이프와 마찬가지로, 선을 추가하고, 과열없이 프로세스를 추가합니다 (생성기이기 때문에). 그리고 당신이 제거되면 retrlines, 목록을 한 번도 저장하지 않기 때문에 더 나은 경우에도 여전히 작동합니다.

편집 : 글쎄, 나는 다른 답변에 대한 의견을 읽었으며 이름에 공간이 있으면 작동하지 않는다고 말합니다.

멋지다, 이것은 왜이 방법이 편리한지를 보여줄 것이다. 프로세스에서 무언가를 변경하려면 줄을 변경합니다. 스왑 :

files = (line.rsplit(None, 1)[1] for line in log)

그리고

# join split the line, get all the item from the field 8 then join them
files = (' '.join(line.split()[8:]) for line in log)

좋아, 이것은 여기서 분명하지 않을 수도 있지만, 거대한 배치 프로세스 스크립트의 경우 좋다 :-)

그건 그렇고, 어떤 이유로 retrlines ()를 사용하는 경우 약간 덜 최적의 방법은 Retrlines ()에 두 번째 인수로 함수를 전달하는 것입니다. 목록의 각 항목에 대해 호출됩니다. 따라서 다음과 같은 것 ( 'ftp'라는 FTP 객체가 있다고 가정)도 작동합니다.

filenames = []
ftp.retrlines('LIST', lambda line: filenames.append(line.split()[-1]))

그런 다음 목록은 파일 이름의 목록이됩니다.

이유가 있습니까? ftplib.ftp.nlst () 당신을 위해 효과가 없습니까? 방금 확인했고 주어진 디렉토리에서 파일의 이름 만 반환합니다.

출력의 모든 파일 이름은 동일한 열에서 시작하므로 첫 번째 줄에서 점의 위치를 ​​가져오기만 하면 됩니다.

drwxrwsr-x 5 ftp-usr pdmaint 1536 Mar 20 09:48 .

그런 다음 해당 점의 위치를 ​​시작 색인으로 사용하여 다른 줄에서 파일 이름을 잘라냅니다.

점이 줄의 마지막 문자이므로 줄 길이에서 1을 뺀 값을 인덱스로 사용할 수 있습니다.따라서 최종 코드는 다음과 같습니다.

lines = ftp.retrlines('LIST')
lines = lines.split("\n") # This should split the string into an array of lines

filename_index = len(lines[0]) - 1
files = []

for line in lines:
    files.append(line[filename_index:])

FTP 서버가 지원하는 경우 MLSD 명령, 그런 다음 "단일 디렉토리 케이스"섹션을 참조하십시오. 저것 대답.

인스턴스를 사용하십시오 (예 : ftpd)의 FTPDirectory 클래스, 전화 .getdata 연결된 방법 ftplib.FTP 올바른 폴더의 인스턴스는 다음을 수행 할 수 있습니다.

directory_filenames= [ftpfile.name for ftpfile in ftpd.files]

나는 그것이 당신을 위해 일해야한다고 믿는다.

file_name_list = [' '.join(each_file.split()).split()[-1] for each_file_detail in file_list_from_log]

메모 -

  1. 여기에서는 콘솔이 아닌 프로그램의 데이터를 원한다고 가정하고 있습니다.

  2. 각 _file_detail은 프로그램에서 생성되는 각 줄입니다.

  3. ''.join (earg_file.split ())

여러 공간을 1 공간으로 교체합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top