重命名文件,其中包含ÖöÇ窪İİıĞüüü

时间:2015-01-27 18:38:38

标签: batch-file cmd

我正在尝试使用批量重命名文件。我想用Ö ö Ç ç Ş ş İ ı Ğ ğ Ü ü替换字母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文件。

2 个答案:

答案 0 :(得分:1)

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

  • 命令行解释器默认使用哪个代码页? CHCP 命令会回答......一般来说:OEM(= 852 DOS:东欧 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"

答案 1 :(得分:1)

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

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

我编写了另一个名为JREN.BAT的混合JScript /批处理实用程序,它通过正则表达式替换重命名文件或文件夹。我没有计划这个,但这是JREN.BAT的完美应用。这是有效的,因为JScript实际上进行了重命名,而JScript本身也适用于unicode。

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

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

1)第一个版本相当容易理解,并且易于维护 - 只需为每个需要的翻译添加额外的“查找替换”行。最大的缺点是性能下降,因为它重复重命名每个文件 - 每个文件要翻译一次。

@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)" ^
          "$1?'O':$2?'o':$3?'C':$4?'c':$5?'S':$6?'s':$7?'I':$8?'i':$9?'G':$10?'g':$11?'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!$0" /j %*

假设您将上述任何脚本命名为“fixUnicode.bat”,并将其与JREN.BAT放在PATH中的某个位置,然后您可以使用以下任何一种:

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

fixUnicode

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

fixUnicode /p "d:\test"

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

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

您可以附加其他选项以指定要包含或排除的文件和/或路径。使用jren /?获取JREN可用的所有选项的帮助。其中大多数可以与fixUnicode.bat

一起使用