如果文件夹名称包含 Unicode 字符,则批处理无法正常工作
Batch does not work correctly if the folder name contains Unicode characters
之前,我被要求创建以下批次。
我以为可以正常使用,但是当文件夹名称包含Unicode字符(❤,㉓等)时,文件夹中的压缩文件一直没有解压。
因此,即使文件夹名称中包含 Unicode 字符,我如何提取它们?
作为另一个问题,如果文件夹中没有压缩文件(zip、rar、partX.rar),则以下批处理不会移动到 done 文件夹。就算文件夹里没有压缩文件,每次都想移动到done文件夹
之前:
C:
│
└─test
├─AAAA
│ XXXX.rar
│ XXXX.jpg
│
├─㉓
│ XXXX.zip
│ XXXX.jpg
│
├─CCCC(error_file)
│ XXXX.rar
│ XXXX.jpg
│
├─DDDD
│ XXXX.part1.rar
│ XXXX.part2.rar
│ XXXX.jpg
│
└─EEEE
XXXX.jpg
之后:
C:
│
└─test
├─done
│ │
│ │
│ ├─AAAA
│ │ XXXX.doc
│ │ XXXX.jpg
│ │
│ ├─㉓
│ │ XXXX.doc
│ │ XXXX.jpg
│ │
│ ├─DDDD
│ │ XXXX.doc
│ │ XXXX.jpg
│ │
│ └─EEEE
│ XXXX.jpg
│
└─CCCC(error_file)
XXXX.rar
XXXX.jpg
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "PromptForBreak="
if /I "%~1" == "/noprompt" set "PromptForBreak=rem"
set "SourceFolder=C:\Test"
set "LogExtract=%SourceFolder%\ExtractionLog.txt"
set "LogError=%SourceFolder%\ErrorLog.txt"
del /Q "%LogExtract%" "%LogError%" 2>nul
for /F "eol=| delims=" %%I in ('dir "%SourceFolder%\*" /AD-H /B /ON 2^>nul ^| %SystemRoot%\System32\findstr.exe /I /L /V /X /C:done') do (
set "ArchiveExtracted="
for /F "eol=| delims=" %%J in ('dir "%SourceFolder%\%%I\*.rar" "%SourceFolder%\%%I\*.zip" /A-D-H /B /ON 2^>nul') do (
if exist "%SourceFolder%\%%I\%%J" (
echo Extracting "%SourceFolder%\%%I\%%J" ...
"%ProgramFiles%\WinRAR\WinRAR.exe" x -cfg- -ibck -logpfu="%LogExtract%" -o+ -y -- "%SourceFolder%\%%I\%%J" "%SourceFolder%\%%I\"
if errorlevel 1 (
set "ArchiveFile=%SourceFolder%\%%I\%%J"
>>"%LogError%" call echo Error %%ErrorLevel%% on extracting "%%ArchiveFile%%"
) else (
set "ArchiveExtracted=1"
echo %%~nJ| %SystemRoot%\System32\findstr.exe /I /R "\.part[0123456789][0123456789]*$" >nul
if errorlevel 1 ( del /F "%SourceFolder%\%%I\%%J" ) else for %%# in ("%%~nJ") do del /F /Q "%SourceFolder%\%%I\%%~n#.part*%%~xJ"
)
)
)
if defined ArchiveExtracted (
md "%SourceFolder%\done" 2>nul
if exist "%SourceFolder%\done\" move /Y "%SourceFolder%\%%I" "%SourceFolder%\done\"
%PromptForBreak% %SystemRoot%\System32\choice.exe /C NY /N /T 2 /D N /M "Break execution [N/Y]? "
%PromptForBreak% if errorlevel 2 goto EndBatch
)
)
:EndBatch
endlocal
在 Windows 8 或更新的 Windows 版本中 Consolas 默认设置为控制台字体 windows 以下批处理文件应该工作:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "tokens=2 delims=:" %%I in ('%SystemRoot%\System32\chcp.com') do set "CodePage=%%I"
%SystemRoot%\System32\chcp.com 65001 2>nul
set "PromptForBreak="
if /I "%~1" == "/noprompt" set "PromptForBreak=rem"
set "SourceFolder=C:\Test"
set "LogExtract=%SourceFolder%\ExtractionLog.txt"
set "LogError=%SourceFolder%\ErrorLog.txt"
del /Q "%LogExtract%" "%LogError%" 2>nul
for /F "eol=| delims=" %%I in ('dir "%SourceFolder%\*" /AD-H /B /ON 2^>nul ^| %SystemRoot%\System32\findstr.exe /I /L /V /X /C:done') do (
set "NoFolderMove="
for /F "eol=| delims=" %%J in ('dir "%SourceFolder%\%%I\*.rar" "%SourceFolder%\%%I\*.zip" /A-D-H /B /ON 2^>nul') do (
if exist "%SourceFolder%\%%I\%%J" (
echo Extracting "%SourceFolder%\%%I\%%J" ...
"%ProgramFiles%\WinRAR\WinRAR.exe" x -cfg- -ibck -logpfu="%LogExtract%" -o+ -y -- "%SourceFolder%\%%I\%%J" "%SourceFolder%\%%I\"
if errorlevel 1 (
set "NoFolderMove=1"
set "ArchiveFile=%SourceFolder%\%%I\%%J"
>>"%LogError%" call echo Error %%ErrorLevel%% on extracting "%%ArchiveFile%%"
) else (
echo %%~nJ| %SystemRoot%\System32\findstr.exe /I /R "\.part[0123456789][0123456789]*$" >nul
if errorlevel 1 ( del /F "%SourceFolder%\%%I\%%J" ) else for %%# in ("%%~nJ") do del /F /Q "%SourceFolder%\%%I\%%~n#.part*%%~xJ"
)
)
)
if not defined NoFolderMove (
md "%SourceFolder%\done" 2>nul
if exist "%SourceFolder%\done\" move /Y "%SourceFolder%\%%I" "%SourceFolder%\done\" >nul
%PromptForBreak% %SystemRoot%\System32\choice.exe /C NY /N /T 2 /D N /M "Break execution [N/Y]? "
%PromptForBreak% if errorlevel 2 goto EndBatch
)
)
:EndBatch
if defined CodePage %SystemRoot%\System32\chcp.com %CodePage%
endlocal
这个批处理文件与之前询问的文件夹移动相反。所有文件夹都移动到子文件夹 done
,而不仅仅是那些成功提取存档文件的文件夹。存档文件提取错误的子文件夹保留在源文件夹中,就像以前的版本一样。
On Windows 7 默认配置为 Raster Fonts,即不支持 UTF-8 的 Terminal。这导致在执行批处理文件期间显示:
The system cannot write to the specified device.
原因被eryksun and can be read in the comments below answer on 分析过一次。
可以通过从批处理文件中删除以下行来避免错误消息:
echo Extracting "%SourceFolder%\%%I\%%J" ...
存档文件提取任务和文件夹移动仍然由 Windows 7 上的批处理文件完成,即使 cmd.exe
.
输出此错误消息也是如此
在 Windows 上,XP 默认还配置了 Raster Fonts,这也是 Terminal 不支持 UTF-8。但是在 Windows XP 上,Windows 命令处理器在第四行后停止执行批处理文件。所以这个批处理文件不能在 Windows XP 上使用,至少不能在不更改进程 运行 这个批处理文件的属性中的字体的情况下使用。
Windows XP 的解决方法是使用仅由 ASCII 字符组成的短 8.3 文件夹名称,正如此批处理文件所做的那样。
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "PromptForBreak="
if /I "%~1" == "/noprompt" set "PromptForBreak=rem"
set "SourceFolder=C:\Test"
set "LogExtract=%SourceFolder%\ExtractionLog.txt"
set "LogError=%SourceFolder%\ErrorLog.txt"
del /Q "%LogExtract%" "%LogError%" 2>nul
for /F "eol=| tokens=4" %%I in ('dir "%SourceFolder%\*" /AD-H /ON /X 2^>nul ^| %SystemRoot%\System32\findstr.exe /L /C:"<DIR>" ^| %SystemRoot%\System32\findstr /I /E /L /V /C:" done" /C:" ." /C:" .."') do (
set "NoFolderMove="
for /F "eol=| delims=" %%J in ('dir "%SourceFolder%\%%I\*.rar" "%SourceFolder%\%%I\*.zip" /A-D-H /B /ON 2^>nul') do (
if exist "%SourceFolder%\%%I\%%J" (
echo Extracting "%SourceFolder%\%%I\%%J" ...
"%ProgramFiles%\WinRAR\WinRAR.exe" x -cfg- -ibck -logpfu="%LogExtract%" -o+ -y -- "%SourceFolder%\%%I\%%J" "%SourceFolder%\%%I\"
if errorlevel 1 (
set "NoFolderMove=1"
set "ArchiveFile=%SourceFolder%\%%I\%%J"
>>"%LogError%" call echo Error %%ErrorLevel%% on extracting "%%ArchiveFile%%"
) else (
echo %%~nJ| %SystemRoot%\System32\findstr.exe /I /R "\.part[0123456789][0123456789]*$" >nul
if errorlevel 1 ( del /F "%SourceFolder%\%%I\%%J" ) else for %%# in ("%%~nJ") do del /F /Q "%SourceFolder%\%%I\%%~n#.part*%%~xJ"
)
)
)
if not defined NoFolderMove (
md "%SourceFolder%\done" 2>nul
if exist "%SourceFolder%\done\" move /Y "%SourceFolder%\%%I" "%SourceFolder%\done\" >nul
%PromptForBreak% %SystemRoot%\System32\choice.exe /C NY /N /T 2 /D N /M "Break execution [N/Y]? "
%PromptForBreak% if errorlevel 2 goto EndBatch
)
)
:EndBatch
endlocal
缺点是移动的目录在子目录 done
中最后是短的 8.3 目录名称,而不是原始目录名称。
之前,我被要求创建以下批次。
我以为可以正常使用,但是当文件夹名称包含Unicode字符(❤,㉓等)时,文件夹中的压缩文件一直没有解压。 因此,即使文件夹名称中包含 Unicode 字符,我如何提取它们?
作为另一个问题,如果文件夹中没有压缩文件(zip、rar、partX.rar),则以下批处理不会移动到 done 文件夹。就算文件夹里没有压缩文件,每次都想移动到done文件夹
之前:
C:
│
└─test
├─AAAA
│ XXXX.rar
│ XXXX.jpg
│
├─㉓
│ XXXX.zip
│ XXXX.jpg
│
├─CCCC(error_file)
│ XXXX.rar
│ XXXX.jpg
│
├─DDDD
│ XXXX.part1.rar
│ XXXX.part2.rar
│ XXXX.jpg
│
└─EEEE
XXXX.jpg
之后:
C:
│
└─test
├─done
│ │
│ │
│ ├─AAAA
│ │ XXXX.doc
│ │ XXXX.jpg
│ │
│ ├─㉓
│ │ XXXX.doc
│ │ XXXX.jpg
│ │
│ ├─DDDD
│ │ XXXX.doc
│ │ XXXX.jpg
│ │
│ └─EEEE
│ XXXX.jpg
│
└─CCCC(error_file)
XXXX.rar
XXXX.jpg
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "PromptForBreak="
if /I "%~1" == "/noprompt" set "PromptForBreak=rem"
set "SourceFolder=C:\Test"
set "LogExtract=%SourceFolder%\ExtractionLog.txt"
set "LogError=%SourceFolder%\ErrorLog.txt"
del /Q "%LogExtract%" "%LogError%" 2>nul
for /F "eol=| delims=" %%I in ('dir "%SourceFolder%\*" /AD-H /B /ON 2^>nul ^| %SystemRoot%\System32\findstr.exe /I /L /V /X /C:done') do (
set "ArchiveExtracted="
for /F "eol=| delims=" %%J in ('dir "%SourceFolder%\%%I\*.rar" "%SourceFolder%\%%I\*.zip" /A-D-H /B /ON 2^>nul') do (
if exist "%SourceFolder%\%%I\%%J" (
echo Extracting "%SourceFolder%\%%I\%%J" ...
"%ProgramFiles%\WinRAR\WinRAR.exe" x -cfg- -ibck -logpfu="%LogExtract%" -o+ -y -- "%SourceFolder%\%%I\%%J" "%SourceFolder%\%%I\"
if errorlevel 1 (
set "ArchiveFile=%SourceFolder%\%%I\%%J"
>>"%LogError%" call echo Error %%ErrorLevel%% on extracting "%%ArchiveFile%%"
) else (
set "ArchiveExtracted=1"
echo %%~nJ| %SystemRoot%\System32\findstr.exe /I /R "\.part[0123456789][0123456789]*$" >nul
if errorlevel 1 ( del /F "%SourceFolder%\%%I\%%J" ) else for %%# in ("%%~nJ") do del /F /Q "%SourceFolder%\%%I\%%~n#.part*%%~xJ"
)
)
)
if defined ArchiveExtracted (
md "%SourceFolder%\done" 2>nul
if exist "%SourceFolder%\done\" move /Y "%SourceFolder%\%%I" "%SourceFolder%\done\"
%PromptForBreak% %SystemRoot%\System32\choice.exe /C NY /N /T 2 /D N /M "Break execution [N/Y]? "
%PromptForBreak% if errorlevel 2 goto EndBatch
)
)
:EndBatch
endlocal
在 Windows 8 或更新的 Windows 版本中 Consolas 默认设置为控制台字体 windows 以下批处理文件应该工作:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "tokens=2 delims=:" %%I in ('%SystemRoot%\System32\chcp.com') do set "CodePage=%%I"
%SystemRoot%\System32\chcp.com 65001 2>nul
set "PromptForBreak="
if /I "%~1" == "/noprompt" set "PromptForBreak=rem"
set "SourceFolder=C:\Test"
set "LogExtract=%SourceFolder%\ExtractionLog.txt"
set "LogError=%SourceFolder%\ErrorLog.txt"
del /Q "%LogExtract%" "%LogError%" 2>nul
for /F "eol=| delims=" %%I in ('dir "%SourceFolder%\*" /AD-H /B /ON 2^>nul ^| %SystemRoot%\System32\findstr.exe /I /L /V /X /C:done') do (
set "NoFolderMove="
for /F "eol=| delims=" %%J in ('dir "%SourceFolder%\%%I\*.rar" "%SourceFolder%\%%I\*.zip" /A-D-H /B /ON 2^>nul') do (
if exist "%SourceFolder%\%%I\%%J" (
echo Extracting "%SourceFolder%\%%I\%%J" ...
"%ProgramFiles%\WinRAR\WinRAR.exe" x -cfg- -ibck -logpfu="%LogExtract%" -o+ -y -- "%SourceFolder%\%%I\%%J" "%SourceFolder%\%%I\"
if errorlevel 1 (
set "NoFolderMove=1"
set "ArchiveFile=%SourceFolder%\%%I\%%J"
>>"%LogError%" call echo Error %%ErrorLevel%% on extracting "%%ArchiveFile%%"
) else (
echo %%~nJ| %SystemRoot%\System32\findstr.exe /I /R "\.part[0123456789][0123456789]*$" >nul
if errorlevel 1 ( del /F "%SourceFolder%\%%I\%%J" ) else for %%# in ("%%~nJ") do del /F /Q "%SourceFolder%\%%I\%%~n#.part*%%~xJ"
)
)
)
if not defined NoFolderMove (
md "%SourceFolder%\done" 2>nul
if exist "%SourceFolder%\done\" move /Y "%SourceFolder%\%%I" "%SourceFolder%\done\" >nul
%PromptForBreak% %SystemRoot%\System32\choice.exe /C NY /N /T 2 /D N /M "Break execution [N/Y]? "
%PromptForBreak% if errorlevel 2 goto EndBatch
)
)
:EndBatch
if defined CodePage %SystemRoot%\System32\chcp.com %CodePage%
endlocal
这个批处理文件与之前询问的文件夹移动相反。所有文件夹都移动到子文件夹 done
,而不仅仅是那些成功提取存档文件的文件夹。存档文件提取错误的子文件夹保留在源文件夹中,就像以前的版本一样。
On Windows 7 默认配置为 Raster Fonts,即不支持 UTF-8 的 Terminal。这导致在执行批处理文件期间显示:
The system cannot write to the specified device.
原因被eryksun and can be read in the comments below answer on
可以通过从批处理文件中删除以下行来避免错误消息:
echo Extracting "%SourceFolder%\%%I\%%J" ...
存档文件提取任务和文件夹移动仍然由 Windows 7 上的批处理文件完成,即使 cmd.exe
.
在 Windows 上,XP 默认还配置了 Raster Fonts,这也是 Terminal 不支持 UTF-8。但是在 Windows XP 上,Windows 命令处理器在第四行后停止执行批处理文件。所以这个批处理文件不能在 Windows XP 上使用,至少不能在不更改进程 运行 这个批处理文件的属性中的字体的情况下使用。
Windows XP 的解决方法是使用仅由 ASCII 字符组成的短 8.3 文件夹名称,正如此批处理文件所做的那样。
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "PromptForBreak="
if /I "%~1" == "/noprompt" set "PromptForBreak=rem"
set "SourceFolder=C:\Test"
set "LogExtract=%SourceFolder%\ExtractionLog.txt"
set "LogError=%SourceFolder%\ErrorLog.txt"
del /Q "%LogExtract%" "%LogError%" 2>nul
for /F "eol=| tokens=4" %%I in ('dir "%SourceFolder%\*" /AD-H /ON /X 2^>nul ^| %SystemRoot%\System32\findstr.exe /L /C:"<DIR>" ^| %SystemRoot%\System32\findstr /I /E /L /V /C:" done" /C:" ." /C:" .."') do (
set "NoFolderMove="
for /F "eol=| delims=" %%J in ('dir "%SourceFolder%\%%I\*.rar" "%SourceFolder%\%%I\*.zip" /A-D-H /B /ON 2^>nul') do (
if exist "%SourceFolder%\%%I\%%J" (
echo Extracting "%SourceFolder%\%%I\%%J" ...
"%ProgramFiles%\WinRAR\WinRAR.exe" x -cfg- -ibck -logpfu="%LogExtract%" -o+ -y -- "%SourceFolder%\%%I\%%J" "%SourceFolder%\%%I\"
if errorlevel 1 (
set "NoFolderMove=1"
set "ArchiveFile=%SourceFolder%\%%I\%%J"
>>"%LogError%" call echo Error %%ErrorLevel%% on extracting "%%ArchiveFile%%"
) else (
echo %%~nJ| %SystemRoot%\System32\findstr.exe /I /R "\.part[0123456789][0123456789]*$" >nul
if errorlevel 1 ( del /F "%SourceFolder%\%%I\%%J" ) else for %%# in ("%%~nJ") do del /F /Q "%SourceFolder%\%%I\%%~n#.part*%%~xJ"
)
)
)
if not defined NoFolderMove (
md "%SourceFolder%\done" 2>nul
if exist "%SourceFolder%\done\" move /Y "%SourceFolder%\%%I" "%SourceFolder%\done\" >nul
%PromptForBreak% %SystemRoot%\System32\choice.exe /C NY /N /T 2 /D N /M "Break execution [N/Y]? "
%PromptForBreak% if errorlevel 2 goto EndBatch
)
)
:EndBatch
endlocal
缺点是移动的目录在子目录 done
中最后是短的 8.3 目录名称,而不是原始目录名称。