Windows XP での国際文字を含むファイル名のバッチ変更
-
09-06-2019 - |
質問
素敵なスウェーデン文字を使ったファイル名を持つファイルが大量にあります å å そして ö。さまざまな理由から、これらを [a-zA-Z] 範囲に変換する必要があります。この範囲外のものを削除するのは非常に簡単です。困っているのは交換したいのですが å と ある, ö と ああ 等々。
これは最悪の場合の文字セットの問題です。
一連のテストファイルがあります。
files\Copy of New Text Documen åäö t.txt
files\fofo.txt
files\New Text Document.txt
files\worstcase åäöÅÄÖéÉ.txt
この行に基づいてスクリプトを作成し、その結果をさまざまなコマンドにパイプしています。
for %%X in (files\*.txt) do (echo %%X)
奇妙なことに、この結果 (単純な for ループ) をファイルに出力すると、次の出力が得られます。
files\Copy of New Text Documen †„” t.txt
files\fofo.txt
files\New Text Document.txt
files\worstcase †„”Ž™‚.txt
そのため、他のツールに到達する前にファイル名に奇妙なことが起こっており(GnuWin32と呼ばれるものからWindows用のSEDポートを使用してこれを実行しようとしましたが、今のところ運がありません)、これらの文字を置換してもうまくいきませんどちらかを助けてください。
この問題をどうやって解決しますか?コマンドラインなど、あらゆる種類のツールを受け入れます…
編集: これは 1 回限りの問題なので、簡単に解決できる方法を探しています
解決
このコード(Python)を使用できます
国際ファイルの名前を変更する
# -*- coding: cp1252 -*-
import os, shutil
base_dir = "g:\\awk\\" # Base Directory (includes subdirectories)
char_table_1 = "áéíóúñ"
char_table_2 = "aeioun"
adirs = os.walk (base_dir)
for adir in adirs:
dir = adir[0] + "\\" # Directory
# print "\nDir : " + dir
for file in adir[2]: # List of files
if os.access(dir + file, os.R_OK):
file2 = file
for i in range (0, len(char_table_1)):
file2 = file2.replace (char_table_1[i], char_table_2[i])
if file2 <> file:
# Different, rename
print dir + file, " => ", file2
shutil.move (dir + file, dir + file2)
###
エンコーディングと文字テーブルを変更する必要があります (このスクリプトをスペイン語のファイルでテストしましたが、正常に動作しました)。「move」行をコメント化して正常に動作しているかどうかを確認し、後でコメントを削除して名前を変更できます。
他のヒント
cmd.exe を UNICODE モードで開いた場合、よりうまくいく可能性があります。「cmd /U」を使用します。
実際のプログラミング言語を使用することを提案する人もいます。特に自分が使い慣れている言語を持っている場合は、それでも問題ありません。C# チームの友人によると、C# 3.0 (Linq を使用) は、このような小規模なプログラムを素早く作成するのに適しているそうです。彼はほとんどの場合、バッチ ファイルを作成するのをやめました。
個人的には PowerShell を選択します。この問題は、コマンドライン上で 1 行で解決できます。病気
編集:1 行ではありませんが、それほど多くのコードではありません。また、StackOverflow は "$_.Name" という構文を好まないようで、_ を _ としてレンダリングします。
$mapping = @{
"å" = "a"
"ä" = "a"
"ö" = "o"
}
Get-ChildItem -Recurse . *.txt | Foreach-Object {
$newname = $_.Name
foreach ($l in $mapping.Keys) {
$newname = $newname.Replace( $l, $mapping[$l] )
$newname = $newname.Replace( $l.ToUpper(), $mapping[$l].ToUpper() )
}
Rename-Item -WhatIf $_.FullName $newname # remove the -WhatIf when you're ready to do it for real.
}
私ならこれを C++、C#、または Java で書きます。これらの環境では、Unicode 文字をパスから適切に取得できることが確実にわかっています。コマンドライン ツール、特に Cygwin の場合は常に不確実です。
この場合、コードは単純な検索/置換または正規表現/置換になります。言語に名前を付けることができれば、コードを書くのは簡単になります。
私なら、ディレクトリをスキャンする vbscript (WSH) を作成し、ファイル名を関数に送信して、ファイル名を個々の文字に分割し、スウェーデン語の文字列に対して SELECT CASE を実行して、必要な文字列に置き換えます。あるいは、それを行う代わりに、関数は一連の REPLACE() 関数を通じてそれをドロップし、出力を入力文字列に再割り当てすることもできます。最後に、ファイルの名前を新しい値に変更します。