Hatena::ブログ(Diary)

名もないテクノ手 このページをアンテナに追加 RSSフィード Twitter

EPUB版『InDesign者のための正規表現入門』

InDesignのTips一覧

2011-05-29

[][][]テキストファイルの文字コードや改行コードを変える。

テキストファイルを扱っている人の多くが文字コードや改行コードを意識していません。こんなこと、今さら言い立てても誰も驚かないでしょう。結果的に、いろんな文字コードのファイルが出入りするので、いつもエディタでちょくちょく直しています。ちょーめんどいです。ファイルがたくさんある時は

nkf -w -Lu --overwrite *.txt

みたいにするといいですよ*1。あ、nkfないですか? この際入れちゃいなさいよ。

nkf Network Kanji Filter プロジェクト日本語トップページ - SourceForge.JP

これでたいていの用は足りるんですけれど、コマンド処理が向かない場合もあります。例えば、処理すべきファイルが細かくフォルダ分けされているとか、フォルダ分けされているとか、フォルダ分けされているとか。いちいちコマンド打ってられっか! ってな気分になります。

(フォルダごと)ドラッグ&ドロップできたら、ちょっとはラクですよね。ということでAppleScriptを書いてみました。

D

文字コードと改行コードだけじゃつまんないので、(字種置換用の)rubyスクリプトも適用できるようにしました。使い方を簡単に説明すると...

  1. ダブルクリック起動で「文字コード」「改行コード」「適用スクリプト」を設定します。*2
  2. 「適用スクリプト」がよくわからなかったら、ファイル選択ダイアログで「キャンセル」をクリックすれば、文字コードと改行コードだけを変えられるようにできます。
  3. あとは処理したいテキストファイル(.txt)をドラッグ&ドロップするだけ。

ダウンロードはこちらです:

Change_text_encoding_and_return_code.zip 直

テキストエディタ「mi」が必要です。nkfは使っていないので、必要ありません。簡単なことしかしてないのに、無意味に長くてクドイですね、すみません。コードはこちら:

(*
Change_text_encoding_and_return_code.app

ドラッグ&ドロップしたテキストファイルのテキストエンコーディングと改行コードを変更して別名保存する。
ラップしたい外部スクリプト(ruby スクリプト)を指定できる。
初期設定はダブルクリックしてダイアログ通りに。
注意事項:処理テキストは拡張子「.txt」が必ず付いていること。

2011-05-28	ver0.1	とりあえず
2011-05-29	ver0.2	テキストであっても「.txt」拡張子を持つものだけを処理するようにした。
2011-05-29	ver0.3	フォルダをドラッグ&ドロップした時、エラーになるのを修正した。
*)

property my_text_encoding : "" --テキストエンコーディング
property my_return_code : "" --改行コード。本来はmiの定数だが、文字列("LF", "CRLF", "CR")で持つようにする。設定の表示のため。
property my_script : "" --rubyスクリプト(置換など)


--------------------------------------------------------●ダブルクリックで設定の変更
on run
	my setting() --セッティングの変更
	display dialog "以下の通りに設定しました" & return & "--" & return & "テキストエンコーディング:" & my_text_encoding & return & "改行コード:" & (my_return_code as Unicode text) & return & "置換スクリプト:" & (my_script as Unicode text)
end run

--------------------------------------------------------●ドラッグ&ドロップされた
on open of theFiles
	--設定
	if my_text_encoding is "" then my setting() --初めて起動された時、セッティング
	
	--設定の表示
	tell application "mi"
		display dialog "ドラッグ&ドロップしたテキストファイルを以下の設定で変換します" & return & "--" & return & "テキストエンコーディング:" & my_text_encoding & return & "改行コード:" & (my_return_code as Unicode text) & return & "置換スクリプト:" & (my_script as Unicode text)
	end tell
	--ファイルのフィルタリング
	set my_files to my file_kind({"txt"}, {""}, theFiles) --拡張子のリスト、ファイルタイプのリスト、処理ファイル	
	--ファイルを開いて、処理
	tell application "mi"
		activate
		repeat with i in my_files
			set tmp_file to my duplicate_rename(content of i) --ファイルの複製とリネーム
			my change_code_and_save(tmp_file) --ファイルを開いて変更し、saveする
			if my_script is not "" then --外部スクリプトが指定されている
				my run_rubyscript(tmp_file) --rubyスクリプトを適用
			end if
		end repeat
		
		display dialog ((length of my_files) as Unicode text) & "ファイルを処理しました"
	end tell
end open


----------------------------------------------●設定
to setting()
	set my_text_encoding to (choose from list {"UTF-8", "UTF-16", "UTF-16LE", "Shift_JIS", "ISO-2022-JP", "EUC-JP", "Shift_JISX0213", "ISO-8859-1", "ISO-8859-2", "ISO-8859-4", "ISO-8859-10", "ISO-8859-13", "ISO-8859-15", "x-mac-roman", "ISO-8859-5", "KOI8-R", "x-mac-cyrillic", "windows-1251", "ISO-8859-7", "x-mac-greek", "windows-1253", "ISO-8859-9", "x-mac-turkish", "windows-1254", "Big5", "GB18030", "GBK"} with prompt "変換したいテキストエンコーディングを指定してください" & return & "(特に意図がなければUTF-8を強く推奨)" default items {"UTF-8"}) as Unicode text
	if my_text_encoding is "false" then error number -128
	
	set my_return_code to (choose from list {"LF", "CR+LF", "CR"} with prompt "変換したい改行コードを指定してください" default items {"LF"}) as Unicode text
	if my_return_code is "false" then error number -128
	try
		set my_script to choose file with prompt "適用するスクリプトを選んでください。" & return & "キャンセルを選ぶと、スクリプトは適用されません。"
	on error errMsg number errNum
		if errNum is -128 then set my_script to ""
	end try
end setting

----------------------------------------------●"LF", "CR+LF", "CR"の文字列をそれぞれmiの定数に変換
to conv_return_code(tmp_return_code)
	tell application "mi"
		if tmp_return_code is "LF" then
			set tmp_return_code to LF
		else if tmp_return_code is "CR+LF" then
			set tmp_return_code to CRLF
		else if tmp_return_code is "CR" then
			set tmp_return_code to CR
		end if
	end tell
	return tmp_return_code
end conv_return_code

----------------------------------------------●必要なファイルだけをフィルタして返します
to file_kind(extention_list, type_list, theFiles)
	set my_files to {}
	
	ignoring case
		tell application "Finder"
			repeat with i in theFiles
				if extention_list contains ((name extension of i) as Unicode text) then
					set end of my_files to contents of i
				else if (kind of i) is "フォルダ" as Unicode text then
					--activate
					--display dialog "フォルダ「" & (name of i) & "」の中の全ファイルを処理します" buttons {"キャンセル", "OK"} default button 2 with icon 0
					set my_files to my_files & my file_kind(extention_list, type_list, every file in folder i)
				else if type_list contains ((file type of i) as Unicode text) then
					set end of my_files to contents of i
				else
					--activate
					--display dialog "ファイル「" & (name of i) & "」は処理ファイルとして不適当です" buttons {"キャンセル", "OK"} default button 2 with icon 0
				end if
			end repeat
		end tell
	end ignoring
	return my_files
end file_kind

----------------------------------●ファイルを複製してリネーム。hoge.txt→hoge_new.txt(miで別名保存ができないための処置)
to duplicate_rename(org_file)
	set org_file to org_file as Unicode text
	set org_file to (quoted form of POSIX path of org_file) --as Unicode text
	set new_filename to do shell script "echo " & org_file & "|sed -e 's/\\.txt$/_new.txt/;'"
	set new_file to do shell script "cp " & org_file & " '" & new_filename & "'"
	return new_filename as POSIX file
end duplicate_rename


----------------------------------●miでドキュメントを開き、テキストエンコーディングと改行コードを変更して保存(別名保存ができないための処置)
to change_code_and_save(tmp_file)
	set tmp_return_code to my conv_return_code(my_return_code)
	try
		tell application "mi"
			open tmp_file
			tell document 1
				set character code to my_text_encoding
				set return code to tmp_return_code
			end tell
			close document 1 saving yes
		end tell
	on error errMsg number errNum
		my my_error("miで処理中にエラーが起きました" & return & errMsg & return & errNum, false)
	end try
end change_code_and_save

----------------------------------●rubyスクリプトを適用
to run_rubyscript(org_file)
	tell application "Finder"
		if not (exists my_script) then my my_error(my_script & "が存在しません", true)
	end tell
	set my_script_posix to quoted form of POSIX path of my_script
	set org_file_posix to quoted form of POSIX path of org_file
	set output_file_posix to quoted form of (do shell script "echo " & org_file_posix & "|sed -e 's/\\.txt$/_new.txt/;'") --出力ファイルパスを生成
	do shell script "ruby " & my_script_posix & " " & org_file_posix & ">" & output_file_posix
	do shell script "rm " & org_file_posix --元ファイルを削除
end run_rubyscript



----------------------------------●エラー処理
on my_error(err_str, my_stop)
	set err_str to err_str as Unicode text
	if my_stop then
		set my_stop to {"中止"}
	else
		set my_stop to {"中止", "続行"}
	end if
	tell application "mi"
		activate
		beep
		set ANS to button returned of (display dialog err_str buttons my_stop default button 1 with icon 0) --警告ダイアログ出してストップ
		if ANS is "中止" then
			error number -128
		end if
	end tell
end my_error

変換するんじゃなくて、確認するだけしたい人は、ものかのさんの「Whisker」を使うと幸せになれますよ。きっとですよ。

*1:このコマンドは、カレントディレクトリの.txtファイルに対して、文字コードUTF-8、改行コードをLFにしています。ファイルは上書きされます。

*2:設定は最初に1回やれば、あとはアプリケーション内に保持されています。設定を変更したいときは、またダブルクリックで起動してください。

ものかのものかの 2011/05/29 03:32 Whiskerをご紹介いただき、あざす!
全部miの実装にまかせるアイデアはさすがです。
piconvちゃんもいい子なので時々使ってあげてください〜

seuzoseuzo 2011/05/29 11:59 ありがとうございます。
Whiskerは一覧で確認できるのがすばらしいです。

piconvは使えるエンコーディングがたくさんあるし、より正確そうです。
piconv派に宗旨替えしちゃおうかしら。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/seuzo/20110529/1306600096