cocoadev 님의 텍스트파일 문자셋 변환 스크립트 를 받아서 유용하게 사용하다가
생각하지 못한 문제에 직면하게 되었다.

일반적으로 파일의 인코딩을 변경하거나 하는 경우는 대개 일반적인 txt 파일이나 데이터 파일이기 때문에
인코딩을 바꿔주는 작업 이외에는 할것이 없다.

하지만 이번에 내가 했던 작업은 소스파일의 인코딩역시 같이 바꾸어 주었기 때문에
인코딩 변경으로 인해서 프로젝트 전체파일들의 실행권한역시 유지 되어야 했는데
아무 생각없이 인코딩 변경하면 유지 되겠거니 했던것이 잘못된 생각 이었다.
인코딩 변경을 할때 기존의 파일을 인코딩하고 이것을 새로 만들어진 파일에 쓰고 파일 이름을 바꾸기 때문에
파일의 실행권한은 유지 되지 않았다.

그래서 cocoadev 님의 스크립트에서 몇줄 추가해 파일의 실행권한도 유지되게끔 수정 해 보았다.
코드에서 # for copy permission… nakada 부분이 내가 수정한 극히 일부분 ~
나도 언젠가 cocoadev 님처럼 처음부터 만들어보고 싶다.

소스코드는 아래 더보기를 누르면 된다 ^^
python 특성상 띄어쓰기로 오류가 있을수도 있기 때문에 파일첨부 !
48fd353d30082CY.py


[#M_더보기|접기|

#!/usr/bin/python
#  -*- coding: utf-8 -*-


import sys, os
from optparse import OptionParser


def change_charset(source, options):
 try:
  old_name = source + '.' + options.save_extension
  os.rename(source, old_name)


  command = 'iconv -f ' + options.old_charset + ' -t ' + options.new_charset + ' ' + old_name + ' > ' + source
  ret = os.system(command)


  # for copy permission... nakada
  st = os.stat(old_name)
  perm = oct(st.st_mode)[-4:]
  os.system(“chmod %(mode)s %(file)s” % {‘mode’:perm, ‘file’:source})
  # end permission


  if ret <> 0:
   print source + ‘   —Fail’
  else:
   if options.nobackup is True:
    os.remove(old_name)
   print source + ‘   …Success’


 except:
  print source + ‘    —Fail’


usage = “%prog -f [options] file1, file2, file3… (or *.txt, *) \n\tor %prog -d<directory> [options]“
parser = OptionParser(usage=usage)


parser.add_option(“-r”, ‘–recursive’, dest=’recursive’, action=’store_true’, default=False, help=’change subdirectory files’)
parser.add_option(“-f”, ‘–files’, dest=’files’, action=’store_true’, default=False, help=’change user input files’)
parser.add_option(“-x”, ‘–nobackup’, dest=’nobackup’, action=’store_true’, default=False,  help=’remove old files’)
parser.add_option(“-d”, ‘–directory’, dest=’directory’, default=”, help=’set working directory’)
parser.add_option(“-s”, ‘–sav’, dest=’save_extension’, default=’chg’, help=’set bakcup file extension(default:chg)’)
parser.add_option(“-e”, ‘–ext’, dest=’extension’, default=’txt’, help=’set working file extension’)
parser.add_option(“-o”, ‘–old’, dest=’old_charset’, default=’euc-kr’, help=’current character set(default:euc-kr)’)
parser.add_option(“-n”, ‘–new’, dest=’new_charset’, default=’utf-8′, help=’new character set(default:utf-8)’)


(options, args) = parser.parse_args()


err_message = ”;
if options.files is True:
 if options.directory <> ”:
  err_message = ‘\’-f\’ and \’-d\’ can\’t be used together’
 if options.recursive is True:
  err_message = ‘\’-r\’ and \’-r\’ cna\’t be used together’
else:
 if options.directory == ”:
  err_message = ‘No working directory’
 else:
  if os.path.isdir(options.directory) is False:
   err_message = options.directory + ‘is invalid directory’


if err_message <> ”:
 print ‘Error: “‘ + err_message + ‘”‘
 parser.print_help()
 sys.exit(0)


if options.files is True:
 argCount = len(sys.argv)
 if argCount is 1:
  print ‘No input files. Try \’chgchar -h\’ for help.’
  sys.exit(0)


 for arg in sys.argv[1:]:
  if os.path.isfile(arg):
   change_charset(arg, options)
else:
 for root, dirs, files in os.walk(options.directory):
  for name in files:
   target_file = os.path.join(root, name)
   target_ext = os.path.splitext(target_file)[1][1:]


   is_change = True


   if options.extension <> ‘*’ and options.extension <> target_ext:
    is_change = False


   if options.recursive is False and os.path.dirname(target_file) <> os.path.dirname(options.directory):
    is_change = False


   if is_change is True:
    change_charset(target_file, options)

_M#]