How Can I Rar a File with a Unicode Name in Batch - windows

I wrote a small batch file to rar all contents in all subfolders within a folder. It works fine except for that the file names should be in ASCII. Below is the working small code:
#REM ------- BEGIN rarthem.bat ----------------
#setlocal
#echo off
echo --------------------------------------------------
echo Starting to rar files
echo --------------------------------------------------
echo.
echo.
echo.
set path="C:\Program Files\WinRAR\";%path%
for /D /r %%G in ("*") do (
echo Storing files in %%G
echo --------------------------------------------------
cd %%G
for %%I in (*.*) do (
rar a -x*.rar -x*.zip -m0 -id[c] "%%~nI.rar" "%%I"
echo Done archiving %%~nI%%~xI
)
echo --------------------------------------------------
echo Done archiving %%~nG
echo --------------------------------------------------
echo.
echo.
cd ..
)
echo Finished!
pause
REM ------- END rarthem.bat ------------------
I think the problem happens when the file name is parsed to WinRAR as WinRAR has no problem archiving files with Unicode names.
Edit: When parsing the file name to WinRAR, the file name gets modified so when WinRAR tries to look for the file under that name, it can't find it. For example a file: téxt.pdf will become text.pdf when parsed.
A small side question: I've not tried using 7zip, would it be easier to achieve the same thing with 7zip?
Many thanks for help.

RAR.exe processes its command-line in the OEM character set (i.e. not unicode). The only way I know of to pass a unicode name to it is via a list file, when also using the argument to specify that the list file is unicode. However, that only works for files inside the archive (EDIT: or files you want to add to the archive). For the archive name itself I don't know of a solution except...
If you use WinRAR.exe instead of RAR.exe then you can pass unicode filenames on the command-line and they work fine. You will see a GUI progress window but other than that (which may or may not matter to you) WinRAR.exe is suitable for running from batch scripts.
Whether a batch script itself can cope with unicode I do not know, but if that is the only problem remaining I would switch to using VBScript or JScript instead of a batch file. (Which is worth doing anyway, IMO. I'm not a big fan of VBScript and JScript but at least they don't have completely insane, arcane semantics and limitations like batch does. :))
By the way, if you do use WinRAR.exe you might want to get the recent WinRAR 4 (beta 2 currently) as it includes the ability to specify the working directory, previously only possible with rar.exe. That can be essential if you need to add files from read-only directories.
If you want to learn about the list files I mentioned, check the RAR.exe text-file document or the WinRAR.exe built-in online help for all the details.
Hope that helps!

Related

Bash robocopy from text file containing path to folders and files to copy with special characters

I had a bash xcopy script, but got a lot of issues. After a lot of searching and reading I guess robocopy was a better tool to do the copy.
(The script must run on windows 10 computers without installing anything else and without internet access)
I'm trying to make a bash script that copy (with robocopy) some local network folders and files to a local custom directory. The aim is to be able to access to the files off from the local network.
The path to folders and files are stored inside a txt file (each line = a path)
I want to keep the structure of folder I save locally.
For example the folder X:\Path\to some\local\network\folder\with\some & characters\ will result in C:\PathTolocalFolder\Path\to some\local\network\folder\with\some & characters\ (without the X:\ letter)
Based on many similar questions (but not all at the same time) I have done this :
#echo off
SETLOCAL EnableDelayedExpansion
cls
cd C:
chcp 28591 > nul
for /f "delims=*" %%a in ('type "X:\path with spaces & specials characters\List.txt"') do (
REM echo %%a
REM echo !%%a!
echo %%a to C:\PathTolocalFolder!%%a!
ROBOCOPY "%%~a" "C:\PathTolocalFolder!%%a!" /S /A+:RA /R:1 /W:5
)
It is partially a success, but :
As there are special characters everywhere in paths and files names, I got some issues. Specially with & characters. My double quotes doesn't solve the problem. How could I go better?
For some cases, I want to save some files but not the whole directory where they are. The full path to the file is inside the text file. But as robocopy needs to add a space between folder path and file filter I have do some manipulation. How can I detect and extract the file name when there is one to adapt the robocopy command?
I want to use an exclusion list like I was doing before with xcopy. But robocopy doesn't accept a file in input for exclusions. I tried this to extract the exclusion file:
for /f "usebackq tokens*" %%D in ("C:\path to exclusion file\exclusions.txt") do (
if NOT "!dirs!"=="" (
Set dirs=!dirs! "%%D"
else (
Set dirs ="%%D"
)
)
But doesn't really know what I am doing and how to combine with the first part.
Bonus questions I'm using the robocopy log file functionality (removed from below) is there a way to archive (by adding the date in the name for example) previous log file before creating the new one? Is it possible to remove the progress percents in the log file but to display it in the terminal instead? How to use the "/np" option for log file but not for terminal display?
It's hard to me to understand how the delayed variables are working in batch files and how the different methods to read a file or variable are working.
Any help is welcome :)
Sorry for my bad English skills
thank for having read

Windows batch scramble/unscramble filenames

I'm looking for a way to scramble/unscramble (encrypt/decrypt) the filenames of every file in a directory via batch script. One .bat file would encrypt the filenames in the current directory, and another would decrypt them.
I have an idea as to how this might work, but lack the batch file skills/experience to make it happen on my own: Have the encryption script find the ASCII value of each character in each filename, increment each character by a certain amount, and then rename each file accordingly. The decryption script would function in a similar but opposite manner. Just an idea - as long as the filename gets fully scrambled and unscrambled, I will be happy.
Any batch file wizards out there willing to lend a hand? Thanks in advance!
Here is a solution that utilizes JREPL.BAT - a regular expression find/replace utility. JREPL is pure script (hybrid JScript/batch) that runs natively on any windows machine from XP onward - no 3rd party exe required.
I used the simple ROT13 substitution cipher Running the script once encrypts the names. Running a second time restores the names to the original values. I chose to encrypt only the file name, not the extension. It would be easy to modify to encrypt the extension as well.
encryptNames.bat
#echo off
pushd %1 .
call :sub
popd
exit /b
:sub Subroutine needed to guarantee %-f0 gives the correct value
setlocal
set "find=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
set "repl=NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm"
set "p=/(.*)/"
set "prepl={$1}"
for /f "delims=" %%C in (
'cmd /c "for %%F in (*) do #if "%%~fF" neq "%~f0" echo ren "%%F" "/%%~nF/%%~xF""^|jrepl find repl /t "" /p p /prepl "{$1}" /v'
) do echo %%C&%%C
Calling encryptNames.bat without any argument will encrypt all files in the current directory (except for the encryptNames.bat file itself)
You can encrypt the names in any folder by passing the folder path as an argument. For example:
encryptNames c:\my\folder\to\be\encrypted
Note that encryptNames.bat assumes JREPL.BAT is in a folder that is listed within your PATH environment variable. If you put JREPL.BAT in the same folder as encryptNames.bat, and then encrypt the files in that folder, then JREPL.BAT will be encrypted, and you will no longer be able to run encryptNames.bat!

Schedule batch file not renaming file to name specified using %date% and %time% variables

As part of a regular file upload process we run a .bat file via Windows Task Scheduler. It opens WinSCPand runs it using a config file.
Then it cds to the file where the upload is stored, renames it, then moves it to the archive file.
If I run the program manually with a pause before the exit, it works fine. Currently is just dumping the file from upload to the archive without renaming it with time and date appended.
#echo off
"C:\Program Files (x86)\WinSCP\winscp.com" /script=CONFIG.txt
cd C:\SCHEDULEDQUERIES\PressGaney\Upload
ren *.csv CL6019_%time:~0,2%%time:~3,2%%date:~-10,2%%date:~3,2%%date:~-4,4%.csv
move *.csv C:\SCHEDULEDQUERIES\PressGaney\archive
exit
Thanks. Happy to give any further details that may be needed.
For lack of further information, I'd suggest
ren *.csv "CL6019_%time:~0,2%%time:~3,2%%date:~-10,2%%date:~3,2%%date:~-4,4%.csv"
should cure the problem. If not, echo this line and then pause the script.
Perhaps your time format - or the time format used by the by the user under which the job is being run by the task scheduler - is set to single-digit hours, which replaces the leading 0 in the time with a space, so the original ren function sees three arguments, not two.
Of course, f you try to debug this during normal working hours, after morning coffee at 10:00 or later, the time won't contain the space, so it seems to work with your tests.
Wrap the batch file to another one and redirect its complete output to a log file:
winscp_script.bat > c:\writable\path\winscp_script.log
Next day, inspect the log file for any errors.
In general, you should not rely on %TIME% and %DATE% variables, as their format is locale specific. The local account that runs your Windows Scheduler task can have a different locale than the one you use to test the batch file. Not only you get a wrong name, but if the resulting format includes spaces, it would completely break the ren command (as already suggested by #Magoo).
WinSCP itself has a built-in feature for time formatting, so you can do something like:
set TIMESTAMP_FORMAT=hhnnddmmyyyy
pushd "C:\Program Files (x86)\WinSCP"
for /F "tokens=* USEBACKQ" %%F in (
`winscp.com /command "echo %%TIMESTAMP#%TIMESTAMP_FORMAT%%%" "exit"`
) do set TIMESTAMP=%%F
popd
echo %TIMESTAMP%
ren *.csv CL6019_%TIMESTAMP%.csv

Win 7: CMD batch file for creating directories based on filenames

I'm working on a CMD line batch file in a Win7 environment that will create directories based upon the filenames listed in a directory.
I am using this code, but the output created is partial and incomplete with only
setlocal enabledelayedexpansion
for /r %%i in (*.wav) do (
set filename1=%%i
set folder1=!filename1:~4,10!
mkdir !folder1!
)
pause
I have this script saved as a CMD file in text format in the source directory, on a local harddrive, though it is in a subdirectory.
The directory output is partial and broken, with garbled output and the numbers of directories created does not match the number of files, and the created directories seem to nest. I've researched this and can't seem to find a definitive answer.
It's not entirely clear what it is you are trying to accomplish. Are you trying to create a directory within the same directory containing the wav file, just without the .wav extension? If so, you're missing some quotation marks and you're stripping the wrong end of the filename off. If that's what you are trying to accomplish, it can actually be done with a single command, no batch script needed. Type this at the command prompt:
for /r %I in (*.wav) do mkdir "%~pnI"
Of course, if you still want it in a batch script, use %%I and %%~pnI with double percents instead of single. See the last couple of pages of help for for an explanation of how %%~pnI works.

Looking for a simple Batch script that modifies file name

I have a list of files in a folder that end with .swf.
I want to change all those files from X.swf to X<some number>.swf.
How can I do that?
This little script will change all *.swf files into the equivalent *_42.swf files.
#setlocal enableextensions enabledelayedexpansion
#echo off
for /f %%a in ('dir /b *.swf') do (
set fspec=%%a
set newfspec=!fspec:~0,-4!_42.swf
echo ren !fspec! !newfspec!
)
endlocal
Actually, as it stands now, it will just echo the commands that it wants to execute. Once you're happy they're correct, you can just remove the echo from that renaming line above.
It works by using for /f to get a list of all SWF files and then using string manipulation to:
remove the last four characters (the.swf extension); then
add a new _42.swf extension onto the end.
And, please, make sure you back them up first :-)
You could use the following one-liner directly from the command prompt:
FOR %F IN (*.swf) DO RENAME "%F" "%~nF123.*"
where 123 stands for your number of choice.
Alternatively you could create a batch file and take advantage of its ability to accept parameters. Use the following script:
#ECHO OFF
SET "suffix=%~1"
FOR %%F IN (*.swf) DO RENAME "%%F" "%%~nF%suffix%.*"
Now if the batch's name is renamer.bat, you can invoke it like this:
renamer.bat 2011
and it will add 2011 to the name of every .swf file in the current directory.
Assuming <X> in your description is supposed to be constant and you don't explicitly require a batch script to solve your problem, you can use Windows Explorer as mentioned in an article by Microsoft titled "Rename a file".
Here's a an extract from said article:
"You can also rename several files at one time, which is useful for grouping related items. To do this, select the files [then press F2]. Type one name, and then each of the files will be saved with the new name and a different sequential number at the end (for example, Renamed File (2), Renamed File (3), and so on)."

Resources