2010-06-24 2 views
5

저는 Python을 커맨드 라인 스크립팅 대체물로 사용하는 법을 배우고 싶습니다. 나는 과거에 파이썬으로 시간을 보냈지 만 그것은 오래되었습니다. 이것은 그것의 범위 내에있는 것으로 보인다.python을 통해 폴더의 모든 파일을 검색하고 교체합니까?

모든 파일 내에서 찾기 및 바꾸기를 수행 할 폴더에 여러 파일이 있습니다. 파이썬 스크립트로하고 싶습니다.

예를 들어 "foo"의 모든 인스턴스를 검색하고 "foobar"으로 바꿉니다.

답변

2

일반적으로 나는 이것에 대한 이전 perl -pi -e 's/foo/foobar/'을 채찍질하려고하지만 파이썬 원하는 경우 :

import os 
import re 
_replace_re = re.compile("foo") 
for dirpath, dirnames, filenames in os.walk("directory/"): 
    for file in filenames: 
     file = os.path.join(dirpath, file) 
     tempfile = file + ".temp" 
     with open(tempfile, "w") as target: 
      with open(file) as source: 
       for line in source: 
        line = _replace_re.sub("foobar", line) 
        target.write(line) 
     os.rename(tempfile, file) 

을 그리고 당신은 윈도우에 있다면, 당신은 os.rename(tempfile, file) 전에 os.remove(file)를 추가해야합니다.

+0

... 원본 파일 백업 sed을 사용하는 모든 텍스트 파일을 발견하고 동시에 단어, 그 내용의 "새"를 "오래된"로 변경 말한다 'tempfile '이 이미 존재하지 않는지를 확인하기 위해 약간의 검사를합니다 ... –

+0

이것은 의미있는 것처럼 보입니다. 임시 파일을 만드는 행위로 권한이 충분하지 않으면 조치를 수행 할 수 있습니까? 이 경우 제거 및 이름 바꾸기가 제대로 작동하지 않습니다. – fruit

+0

임시 파일은 실제 파일을 너무 일찍 덮어 쓰지 않아 큰 파일에서 많은 양의 메모리를 사용하지 않도록합니다. 순진한 방법은 다음과 같습니다.'data = open (file) (데이터) _read(); 데이터 = _replace_re.sub ("foobar", 데이터); 열기 (파일, "승") 쓰기 (데이터)',하지만 그것은 많은 메모리를 사용하고, 컴퓨터가 절반 정도 충돌 한 경우 'write'라면, un-written data를 잃어 버릴 것입니다.) –

1

나는이 작업을 수행 한 것으로 보이지만 지적 될 수있는 오류는 굉장합니다.

import fileinput, sys, os 

def replaceAll(file, findexp, replaceexp): 
    for line in fileinput.input(file, inplace=1): 
     if findexp in line: 
      line = line.replace(findexp, replaceexp) 
     sys.stdout.write(line) 

if __name__ == '__main__': 
    files = os.listdir("c:/testing/") 
    for file in files: 
     newfile = os.path.join("C:/testing/", file) 
     replaceAll(newfile, "black", "white") 

이렇게 확장하면 폴더 내의 폴더로 이동하게됩니다.

+0

'replaceAll (file, "black", "white")'로 바꾸고 싶을 수도 있습니다.'somedir/blackdir/blackfile.txt' 그러면'somedir/whitedir/whitefile.txt'가 나타납니다.물론 원하는 경우가 아니라면 원하는 경우가 아니면 그냥 그대로 두십시오. –

+0

이 함수가 파일의 이름을 바꾸는 이유는 무엇입니까? 그것은 줄 단위로 검색하고 있습니다 .. – fruit

5

Welcome to StackOverflow. 너 자신을 배우고 싶기 때문에 (+1) 나는 몇 가지 조언을 해줄 것이다.

모든 파일을 보려면 os.walk()을 확인하십시오.

그런 다음 파일의 각 행을 반복합니다 (여기서는 for line in currentfile:이 유용합니다). ? 당신이 결과로 foofoobar을 싶어) 또는 스마트 교체 -

지금 당신은 단어의 중간에 경우에도 (예를 들어 foobarfoo 찾기/바꾸기 (교체 당신이 "바보"를 원하는 경우 알 필요가있다.

이전에 대한

, str.replace() 보면 후자 무엇 r'\bfoo\b' 수단을 re.sub()을보고 알아.

+0

정말 고마워! 새로운 기능 (os.walk())에 대해 배우는 것은 언제나 좋습니다. 하위 디렉토리를 통과합니까? 나는 너의 연결이 나에게 말할 것이라는 점을 당연하다고 생각하고있다. – fruit

+0

예, 그렇습니다. :) –

0

이 대안입니다, 당신은. 가장 유용한 유틸리티를 당신에게 제공 다양한 파이썬 솔루션이 있기 때문에 (나에 따르면, 유닉스/윈도우에서, GNU find 명령과 sed/awk와 같은 대체 도구가있다. iles (재귀 적으로) 그리고 교체를하면, 이와 같은 간단한 명령이 트릭을 수행한다 (구문은 메모리에서 나오고 테스트되지 않는다). 넣어하는 것이 좋을 것입니다, 또한

$ find /path -type f -iname "*.txt" -exec sed -i.bak 's/old/new/g' "{}" +; 
관련 문제