[파이썬] 지정한 폴더/확장자에서 텍스트 일괄 변경

2018. 2. 6. 21:44개발/파이썬

 

이번 예제는 지정된 폴더의 특정 확장자를 가진 모든 파일을 열고 변경하고자 하는 텍스트를 모두 찾아 변경 합니다 

(일반적인 Replace All 과 동일)

 

아래 예제는 d:\log 폴더에서 '.log' 확장자를 가진 파일을 대상으로 'text1' 이라는 단어를 찾고 'text2' 로 변경 합니다 (하위 폴더 포함)

예제를 통해 

  • ASCII 파일과 UTF-8 파일 텍스트를 읽고 씁니다. 
  • UTF-8 의 경우 codecs의 도움을 받아야 합니다. 우선 ascii 방식으로 읽고 exception 이 나면 utf-8 방식으로 읽도록 했습니다 
  • 읽기 전용인 경우 쓰기 가능하도록 변경하고 기록 합니다.
  • file::readlines() 를 이용하면 텍스트 파일을 한번에 list 에 넣어 주기 때문에 파일 읽는 노가다가 상당히 줄어 듭니다. (파이썬 만세)
  • 하위 폴더를 탐색하기 위해 이번에도 재귀 함수를 호출합니다 ^^
import sys
import win32con, win32api, os
import codecs  # utf-8 읽어 오기 위해


class CReplaceAllText():
    def __init__(self, path, fromText, toText):
        self.cntFiles = 0
        self.path = path
        self.FromText = fromText
        self.ToText = toText

    # lookupExt : 대상 확장자(.java)
    def startReplaceText(self, path, lookupExt):
        for fname in os.listdir(path) :
            fullname = os.path.join(path, fname)

            if os.path.isdir(fullname) :
                self.startReplaceText(fullname, lookupExt)

            elif os.path.isfile(fullname) :
                ext = os.path.splitext(fullname)[-1]
                if ext != lookupExt:
                    continue

                ret = self.replaceText(fullname)
                self.cntFiles += ret

        if (path == self.path) :
            print('%s --> %s 로 변경, 변경 개수 %d' %(self.FromText, self.ToText, self.cntFiles))



    def replaceText(self,filename):
        bIsUtf = False
        f = open(filename, "r")
        try :
            lines = f.readlines()
        except:
            bIsUtf = True
            f.close()
            f = codecs.open(filename, "r", 'utf-8')
            lines = f.readlines()
        f.close()

        bFind = False
        wlines = []
        for line in lines :
            wline = line
            if self.FromText in line:
                bFind = True
                wline = wline.replace(self.FromText, self.ToText)
            wlines.append(wline)

        if bFind == False:
            return 0

        # 파일이 읽기 전용일 경우 쓰기 가능으로 변경
        win32api.SetFileAttributes(filename, win32con.FILE_ATTRIBUTE_NORMAL)

        if bIsUtf == False:
            f = open(filename, 'w')
            print('%s --> %s 로 변경 %s' % (self.FromText, self.ToText, filename))
        else:
            f = codecs.open(filename, "w", 'utf-8')
            print('%s --> %s 로 변경 %s(utf-8 format)' % (self.FromText, self.ToText, filename))

        f.writelines(wlines)
        f.close()
        return 1


if __name__ == "__main__":
    lookupPath = 'D:\\log'
    # D:\dev\prj\hello\log
    objRep = CReplaceAllText(lookupPath, 'text1', 'text2')
    objRep.startReplaceText(lookupPath, '.log')




Colored by Color Scripter
cs