Previously, I was asked to create the following batch.
How can I extract multiple archives to each folder with WinRAR command line?
I thought it was working properly, but when the folder name contained Unicode characters(❤, ㉓ etc), the compressed file in the folder was never decompressed. Therefore, how can I extract Unicode characters even if they are included in the folder name?
As another problem, the following batch does not move to the done folder if there are no compressed files (zip, rar, partX.rar) in the folder. Even if there are no compressed files in the folder, I want to move to the done folder each time.
Before:
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
After:
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
On Windows 8 or a newer Windows version with Consolas set by default as font for console windows the following batch file should work:
@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
This batch file makes the opposite as previously asked regarding to folder movement. All folders are moved to subfolder done
, not only those in which an archive file was extracted successfully. Subfolders with an error on archive file extraction remain in source folder like in previous version.
On Windows 7 is configured by default Raster Fonts which is Terminal which does not support UTF-8. This results in getting displayed during execution of the batch file:
The system cannot write to the specified device.
The reason was analyzed once by eryksun and can be read in the comments below answer on Using another language (code page) in a batch file made for others.
The error message can be avoided by removing from batch file the line:
echo Extracting "%SourceFolder%\%%I\%%J" ...
The archive file extraction task and folder movement is done nevertheless by the batch file on Windows 7 even on output of this error message by cmd.exe
.
On Windows XP is configured by default also Raster Fonts which is also Terminal not supporting UTF-8. But On Windows XP the Windows command processor stops execution of the batch file after fourth line. So this batch file cannot be used on Windows XP, at least not without changing the font in properties of process running this batch file.
A workaround for Windows XP would be using short 8.3 folder names which consist of only ASCII characters as done by this batch file.
@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
The disadvantage is that the moved directories have in subdirectory done
finally the short 8.3 directory names and not the original directory names.