How to get a batch file to handle spaces in file names? - batch-file

I am using the following batch file to make a zip file for each xml in a folder:
FOR %%f in ("C:\files\*.xml") DO 7za.exe a C:\files\zips\%%~nf.zip (%%f)
However if the file name has a space in it (test plop.xml) then the batch file does not work. It seems to split the name and thinks it is 2 files.
How to modify the batch file so that it properly handles file names with spaces?

Try placing quotes around the output file name.
Change
FOR %%f in ("C:\files*.xml") DO 7za.exe a C:\files\zips\%%~nf.zip (%%f)
to:
FOR %%f in ("C:\files*.xml") DO 7za.exe a "C:\files\zips\%%~nf.zip" (%%f)
May also be the variable %%f, may need to place quotes around this as well.

Related

Windows command line renaming files in subfolders?

I didn't find so far a similar question, so I try to explain the problem:
I have large number of files that are in subfolders inside "C:\images"
I have a list of names in two columns, so that 1st column is old filename and 2nd is a new filename. I want to change that list into a batch file.
Names are pretty unique so I want to make batch file - so that will be one command for every file to be renamed.
RENAME "C:\images\768e11ab.jpg" "4ca5d042.jpg"
RENAME "C:\images\5402c708.jpg" "b802820b.jpg"
RENAME "C:\images\1c039e0e.jpg" "80ce9797.jpg"
etc...
It is rather simple, only, files are scattered across subfolders. Is there any way to make a command so it will look for that specific file in all subfolders in "C:\images" and rename it.
Following some similar questions tried this, with no result:
for /r "C:\images\" "%%~G" (768e11ab.jpg) do "4ca5d042.jpg"
Also, tried to use some renaming application for this but they freeze when I try to rename big list of files, so I would avoid them and use batch file. Also, I would like to use this way where there is one line in batch file for every file because it is simpler for me to use it (and change it later). I appreciate your help.
Approach the problem from the other side. Instead of looping over the image files, loop over the text file.
Assuming your textfile to be something like
"768e11ab.jpg" "4ca5d042.jpg"
"5402c708.jpg" "b802820b.jpg"
"1c039e0e.jpg" "80ce9797.jpg"
Then the code could look like:
#echo off
REM read each line; %%A is the first column, %%B is the second one
for /f "tokens=1,2" %%A in (list.txt) do (
REM search the image file %%A
for /R "C:\Images\" %%C in ("%%~A") do (
REM %%C now holds the full path of %%A
ECHO ren "%%~C" "%%B~%%~xC"
)
)
If your list looks different, the tokens and perhaps the delims for the for /f loop have to be adapted.
NOTE: the ren command is just echoed for security reasons. Once you verified it does exactly what you want, remove the ECHO to enable the * ren` command.

How to rename a file while it is being copied and copy complete

I want to create a script which should copy files from one folder to another.
Since a file can be of a large size, of up to 1000 MB, it may take few seconds
or a minute to completely copy it. While this is being happened, I want the filename in a destination folder to be prefixed with an underscore(_).
Once the file is completely copied over to a destination folder, then the _ should be removed from the filename. The purpose of doing this is to make sure that another process should not pick up the incomplete file from the destination folder.
How can we do this using a batch script? Currently my batch file is copying and moving the file to another folder but I don't know how can i prefix underscore and then remove again from the filename after the file is completely moved.
Here is my 2 line code which is copying and moving the file.
copy %1\Customer_*.xml C:\Users\ard\Documents\Folder1
move %1\Customer_*.xml %1\Archive
If this can't be done using batch script, then VB script should also work
What you want, in words:
For each affected file in C:\source:
Copy file x to C:\destination\_x
Rename file C:\destination\_x to C:\destination\x
and in Windows batch code, with a few extras:
#echo off
setlocal
set "SOURCE=%1"
set "DESTINATION=C:\Users\ard\Documents\Folder1"
for /f "usebackq delims=" %%x in (`dir /b "%SOURCE%\Customer_*.xml"`) do (
if exist "%DESTINATION%\%%x" (
echo %%x - already exists at destination
) else (
echo %%x
copy "%SOURCE%\%%x" "%DESTINATION%\_%%x" > NUL && rename "%DESTINATION%\_%%x" "%%x"
)
)
Notes:
the for loop can iterate a command's output line-wise
in our case, that command is dir /b "%SOURCE%\*.xml", i.e. the "bare" list of matching files in the source folder
usebackq means the command is delimited by backticks, which allows using double quotes inside the command itself
delims= sets the field delimiters to "none", otherwise for would split each filename into tokens if it contained spaces
> NUL suppresses the "1 file(s) copied." success messages from copy
&& means that rename is only executed if copy was successful
Removing a prefix is not trivial, but removing a suffix (new extension) is simple. So I would append a new extension like .inProgress. You can then COPY and RENAME a collection of files with two simple commands using wildcards.
But the MOVE command does not allow renaming multiple files, so a FOR loop would be required. I'll show the code, but I don't think it is really necessary in the OP's scenario. It looks to me like the source and destination folders are on the same drive, so the move should be virtually instantaneous, and there should be no need to use a temporary intermediate name.
copy "%1\Customer_*.xml" "C:\Users\ard\Documents\Folder1\*.*.inProgress"
ren "C:\Users\ard\Documents\Folder1\*.inProgress" *.
for %%F in ("%1\Customer_*.xml") do (
move "%%F" "%1\Archive\%%~nxF.inProgress"
ren "%1\Archive\%%~nxF.inProgress" *.
)
See How does the Windows RENAME command interpret wildcards? for information on why the rename works.
Note that all the copied files will show up as ".inProgress" until the entire COPY operation has completed. If you want each file to be available as soon as possible, then a FOR loop is needed for the COPY as well:
for %%F in ("%1\Customer_*.xml") do (
copy "%%F" "C:\Users\ard\Documents\Folder1\%%~nxF.inProgress"
ren "C:\Users\ard\Documents\Folder1\%%~nxF.inProgress" *.
)
My example copies from src to dest with a new name, then restores back the old name:
bn is the basename of the source file.
for %%a in (src\*.xml) do (
set bn=%%~nxa
copy %%a dest\!bn!_
rename dest\!bn!_ !bn!
)

Batch file rename reading old file name and new file name from a txt file

I have done some searching and reading but I have not been able to find a solution. I apologize if this issue is already answered on the forum. Here is what I want to do:
I have many 1000's of files that I need to rename. I can easily create a .txt file that lists the old file name and the new file name as follows:
oldfilename1.ext newfilename1.ext
oldfilename2.ext newfilename2.ext
oldfilename3.ext newfilename3.ext
etc......
The actual file names will be as follows:
TKP-RL-MB-00205-001.pdf SDY-352-20009SA10BA-RXW03-001.pdf
TKP-RL-MB-00060-004.pdf SDY-352-20010SA10BA-RXW03-004.pdf
etc....
I would like a batch file that reads the two names from the txt file and renames the file from the old name to the new name. The batch file will be located in the same directory as all the files with the old file name. I don't need functionality to check if the old file exists unless that functionality is essential to the batch file working.
I am working in Microsoft Windows 7 so I have cmd and Powershell at my disposal.
Your help is greatly appreciated.
Thank you
This should do what you have described. Remove the echo after the do when you have tested it - atm it will merely print the commands to the screen.
#echo off
for /f "usebackq tokens=1,*" %%a in ("file.txt") do echo ren "%%a" "%%b"
pause
for /f "tokens=1,2" %%a in (yourtextfile.txt) do ECHO ren "%%a" "%%b"
-assuming that the only spaces in the file are those separating the names.
Reduce %% to % to execute directly from the prompt.
The required REN commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO REN to REN to actually rename the files.
If you have that textfile, you might just put a rename at the beginning of each line and save it as .bat.
(E. g. with Notepad++, Search Mode = Extended, replace \n with \nrename, maybe check first and last lines)

.bat file to move files based on extension, spaces in filename

I've been trying to move some files into another folder, based on the file extension. Only problem is that the filenames have spaces in them.
In cmd prompt to move a single file I guess it would look like:
D:\move "D:\folder1\140227 file.xls" D:\folder2
In a bat file I've got:
for /R in D:\folder1 %%f (*.xls) do move %%f D:\folder2\
But obviously that doesn't work due to the lack of quotation marks...
for /R "D:\folder1" %%f in (*.xls) do move "%%f" "D:\folder2\"
..so put the quotes in...
(in keyword misplaced)

Use Dos commands to copy file and preserve date in file name

I'm having trouble trying to copy and rename a file using only dos commands. I have a file of the format myfile20130218 and want to copy and rename it to some_other_file_20130218.
I know I can use copy source dest but I'm having trouble with how to isolate the date and preserve it. I cannot guarantee that he date will be today's date so that is ruled out, the source file will always be the same name.
I can run either a series of commands or a batch script, but thing that that I am currently having trouble with, is after I find a match that I need to copy, using myfile????????, how can I now get those file names to pull the dates off them?
EDIT: for clarification I will be looking at files in a known directory, as above, I will know the format of the file name, and will only be checking a specific directory for it. The process that checks the directory is a ConnectDirect file watcher, so when a file is found matching myfile20130218 I can fire off some commands, but don't know how to check the directory and get the name of the file present.
Something like this should work:
%oldname:~-8% extracts the last 8 characters from %oldname% which are then appended to the new filename.
Update: If you can identify the file with an external program and then call the batch script with the file name
copyfile.cmd C:\path\to\myfile20130218
you could do something like this:
set oldname=%~nx1
set newname=%~dp1some_other_file_%oldname:~-8%
copy "%~f1" "%newname%"
Update 2: If you know folder and the format you could call the script with the folder
copyfile.cmd C:\folder
and do something like this:
#echo off
setlocal EnableDelayedExpansion
for /f %%f in (
'dir /b "%~f1" ^| findstr /r "myfile[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$"'
) do (
set oldname=%~f1\%%f
set newname=%~f1\my_other_name_!oldname:~-8!
copy "!oldname!" "!newname!"
)
endlocal
Edit: Script breakdown.
setlocal EnableDelayedExpansion enables variable expansion inside loops and conditionals.
for /f %%f in ('...') executes the command between the single quotes and then loops over the output of that command.
dir /b "%~f1" lists the content of the given directory (%~f1 expands to the full path of the first argument passed to the script) in simple mode (no header, no summary).
findstr /r "myfile[0-9]...[0-9]$" filters the input for strings that end with the substring "myfile" followed by 8 digits. The circumflex before the pipe (^|) escapes the pipe, because otherwise it would take precedence over the for command, which would effectively split the for command in half, resulting in an invalid command-line.
set oldname=%~f1\%%f assign the full path to a matching file to the variable oldname.
set newname=%~f1\my_other_name_!oldname:~-8! assign the full path to the new filename ("my_other_name_" followed by the trailing 8 digits from oldname) to the variable newname.
copy "!oldname!" "!newname!" I don't need to explain this, do I?

Resources