重命名包含的文件

Renaming file which is contain Ö ö Ç ç Ş ş İ ı Ğ ğ Ü ü

我正在尝试使用批处理重命名文件。我想用 O o C c S s I i G g U u 替换字母 Ö ö Ç ç Ş ş İ ı Ğ ğ Ü ü 但它失败了。我能做些什么来解决这个问题。

@echo OFF
set TargetFolder=%~dp0target
setlocal enableDelayedExpansion
set srch=Ö ö Ç ç Ş ş İ ı Ğ ğ Ü ü
set rplc=O o C c S s I i G g U u
set /a n=0

for %%a in (!srch!) do set /a n+=1&set srch[!n!]=%%a
set /a n=0
for %%a in (!rplc!) do set /a n+=1&set rplc[!n!]=%%a

for /f "tokens=* delims=" %%a in ('dir /b /a-d "%TargetFolder%\*"') do (
  set NewFileName=%%~na
  for /l %%x in (1,1,!n!) do (
    for /f "tokens=* delims=" %%t in ('jrepl !srch[%%x]! !rplc[%%x]! /s NewFileName') do set "NewFileName=%%t"
  )
  ren "%TargetFolder%\%%~nxa" "!NewFileName!%%~xa"
)
endlocal
pause

PS: 此代码需要来自@dbenham 的 JREPL.BAT 文件。

更改为正确的代码页。提示:

  • 命令行解释器默认使用哪个代码页? CHCP 命令会回答... 一般:OEM ( =852 DOS: East Europe on 我的 Windows)。
  • 脚本保存为哪个代码页?一般: ANSI ( =1250 Windows: 东欧 我的Windows)

下一个脚本 cpansi.bat 保存为 ANSI

echo OFF
setlocal enableDelayedExpansion
set "srch=Ö ö Ç ç Ş ş İ ı Ğ ğ Ü ü"
set "rplc=O o C c S s I i G g U u"
echo srch %srch%
echo rplc %rplc%
endlocal
goto :eof

输出:

Active code page: 852

d:\bat>cpansi

d:\bat>echo OFF
srch Í ÷ ă š ¬ ║ I i G g ▄ Ř
rplc O o C c S s I i G g U u

d:\bat>chcp 1250
Active code page: 1250

d:\bat>cpansi

d:\bat>echo OFF
srch Ö ö Ç ç Ş ş I i G g Ü ü
rplc O o C c S s I i G g U u

编辑:将ren更改为echo并临时添加dir以进行调试以查看会发生什么:

echo ren "%TargetFolder%\%%~nxa" "!NewFileName!%%~xa"
dir /B "%TargetFolder%\%%~nxa"

问题字符是没有 ASCII 等效字符的 Unicode。文件系统允许这样的 unicode 字符,但命令行对 unicode 的支持有限。

通过使用 \uNNNN 转义序列,可以使用 JREPL 操作 unicode 字符。但即使您正确地执行了此操作,命令行也会在您尝试重命名文件时损坏该值。

我编写了另一个名为 JREN.BAT 的混合 JScript/batch 实用程序,它通过正则表达式替换重命名文件或文件夹。我没有计划这样做,但这是 JREN.BAT 的完美应用程序。这是有效的,因为 JScript 实际上进行了重命名,并且 JScript 本机使用 unicode。

为了重命名,您必须首先为问题字符建立 unicode 代码值。我将字符复制到 MicroSoft Word 文档中,并使用 http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=UTTUsingUnicodeMacros 中描述的过程计算出代码值。

我用JREN写了三个解决方案。

1) 第一个版本很容易理解,也很容易维护 - 只需为每个需要的翻译添加额外的
"find replace" 行。最大的缺点是性能低下,因为它会重复重命名每个文件 - 每个要翻译的字符一次。

@echo off
for %%A in (
  "00D6 O"
  "00F6 o"
  "00C7 C"
  "00E7 c"
  "015E S"
  "015F s"
  "0130 I"
  "0131 i"
  "011E G"
  "011F g"
  "00DC U"
  "00FC u"
) do for /f "tokens=1,2" %%B in (%%A) do call jren "\u%%B" "%%C" %*

2) 第二个版本有点难以遵循,而且难以维护。但它要快得多,因为它一次性完全重命名每个文件。

@echo off
call jren "(\u00D6)|(\u00F6)|(\u00C7)|(\u00E7)|(\u015E)|(\u015F)|(\u0130)|(\u0131)|(\u011E)|(\u011F)|(\u00DC)|(\u00FC)" ^
          "?'O':?'o':?'C':?'c':?'S':?'s':?'I':?'i':?'G':?'g':?'U':'u'" /j %*

3) 最后一个版本提供了两全其美的优势。翻译列表像第一个版本一样易于维护,但它会动态构建搜索和替换表达式,供第二种方法使用。所以它能够一次重命名所有文件。

@echo off
setlocal enableDelayedExpansion
set "find="
set "repl="
set /a n=0
for %%A in (
  "00D6 O"
  "00F6 o"
  "00C7 C"
  "00E7 c"
  "015E S"
  "015F s"
  "0130 I"
  "0131 i"
  "011E G"
  "011F g"
  "00DC U"
  "00FC u"
) do for /f "tokens=1,2" %%B in (%%A) do (
  set /a n+=1
  set "find=!find!|(\u%%B)"
  set "repl=!repl!$!N!?'%%C':"
)
call jren "!find:~1!" "!repl![=12=]" /j %*

假设您将上述任何脚本命名为 "fixUnicode.bat" 并将其与 JREN.BAT 一起放在您的 PATH 中的某处,那么您可以使用以下任何脚本:

重命名当前目录下的所有文件

fixUnicode

重命名 d:\test 文件夹中的所有文件

fixUnicode /p "d:\test"

递归重命名 c: 驱动器上的所有文件和文件夹

fixUnicode /s /p "c:\"
fixUnicode /d /s /p "c:\"

您可以附加其他选项来指定要包含或排除哪些文件 and/or 路径。使用 jren /? 获取有关 JREN 可用的所有选项的帮助。其中大部分可以与 fixUnicode.bat

一起使用