Windows command line renaming files in subfolders? - batch-file

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.

Related

Batch file to rename files with complex names and back again

Reviving an old topic once discussed here, as I have a similar problem. The solution proposed in the old thread worked only in half in my case.
I need first to rename various media files (mp4, mp3, wav...) with irregular, sometimes complex names as 1.mp3, 2.mp4, 3.wav, etc. And some time after I need to restore the original filenames. File extensions should remain the same in both cases.
In a more specific case of renaming .raw files Helbreder proposed two .bat scripts. The first .bat changes filenames to 1.raw, 2.raw, 3.raw, etc. and creates corresponding individual .txt files each of which keeps the original filename. The second .bat takes the original filenames from individual .txt files and renames 1.raw, 2.raw, 3.raw, etc., back to the original.
For my purpose I slightly modified the first .bat proposed, and this works perfectly well:
#echo OFF
#setlocal ENABLEDELAYEDEXPANSION
set I=1
for %%G in (*.mp3 or *.3gp or *.wav or .mp4) do (
set ORIGINAL_NAME=%%~nG
set ORIGINAL_EXTENSION=%%~xG
(
REM Try to rename file
ren "%%G" "!I!"!ORIGINAL_EXTENSION!
) && (
REM Renaming was successful
> "!I!.txt" echo !ORIGINAL_NAME!!ORIGINAL_EXTENSION!
set /A I+=1
) || (
REM Renaming was a failure
echo Cannot rename [!ORIGINAL_NAME!] file.
)
)
#endlocal
Put in a destination directory, this .bat renames all media files, keeping the correct extensions, and generates a set of .txt files each of which contains the original filename with extension.
For instance, 1.txt contains a string "Play 2019-03-06 in C.mp3" which was the original filename.
Then I need to reverse the original filenames and I run the second unmodified Helbreder's .bat. For commodity purpose I paste it here:
#echo OFF
#setlocal ENABLEDELAYEDEXPANSION
for %%F in (*.txt) do (
set BASENAME=%%~nF
REM Read original name from txt file
for /F %%G in (%%F) do (
REM iterate over all corresponding files
for %%H in (!BASENAME!.*) do (
set EXTENSION=%%~xH
REM Remove dot from extension string
set EXTENSION=!EXTENSION:~1!
if not "!EXTENSION!" == "txt" (
REM Process files
(
REM try to rename corresponding file to old name
ren "!BASENAME!.!EXTENSION!" "%%G.!EXTENSION!"
) && (
REM Operation was successful - remove TXT file
del /F /Q "%%F"
) || (
REM Something went wrong
echo Cannot restore old name for file [!BASENAME!.!EXTENSION!].
)
)
)
)
)
#endlocal
As my filenames may be complex and often include blank spaces, this second .bat works in a half-successful way.
It reverted the first original filename "Play 2019-03-06 in C.mp3" written to a 1.txt with extension, as simply "Play.mp3". It also ignored a part of the second complex filename which followed blank space, keeping only "2007-03-06.mp3" instead of "2007-03-06 output.mp3". And it successfully reverted only those filenames which were composed of numbers and underscores, without blank spaces.
As far as I understand, the issue consists in the way the second .bat retrieves the filename from the text string kept in .txt file. The first blank space occurring in the text line is considered as the end of a filename.
Could you kindly suggest a solution for reverse renaming of any files from the correspondent .txt record, which may contain letters, numbers and blank spaces (and maybe special characters, like "&" and some others).
Following Compo's advise I tried another code from the old post, this time proposed by Jeb.
After a slight modification to make it match to different file types and - important! - to keep their original extensions, the code seems to work, but with issues.
When there is more than one dot in the filename the name revert code does not restore it completely, even though it is correctly saved in the .txt file by the rename batch. For example the second batch truncates "Play 2020.10.12.mp4" to "Play 2020" and does not wish to restore the extension.
Placed in directories with many files the rename batch sometimes does not rename a part of the list, sometimes does not do the job at all and sometimes renames all files flawlessly. I first thought the partial script dysfunction might be related to the presence of special signs in the filenames, like commas or parenthesis. But no, when I delete special signs, this changes nothing. Just puzzled.
So, the new version of code is only partially solving the problem. Is there something to correct in the code, to make it more universally working? Which solution could be applied in these two cases?
I divided the code into two separate .bat files to rename and to revert original filenames.
The both follow.
Rename:
#echo off
set cnt=0
del Names.txt > nul 2>&1
echo Running Batch Rename
for %%f in (*.mp3 or *.mp4 or *.3gp or *.wav) do (
set "file=%%f"
set "EXTENSION=%%~xf"
CALL :renameToNumber
)
:renameToNumber
set /A cnt+=1
set "number=00000%cnt%"
set "number=%number:~-4%"
(echo %number% %file%) >> Names.txt
ren "%file%" %number%"%EXTENSION%"
exit /b
Revert the original names:
for /F "tokens=1,*" %%A in (names.txt) DO (
set "number=%%A"
set "filename=%%~nB"
call ren %%number%%.* "%%filename%%.*"
call echo ren %%number%%.* "%%filename%%.*"
)
exit /b

Windows Batch - Rename files with period before extension

I'm on Windows 10, and I'm writing a batch file to convert many images from one format to another and renaming a helper file that generates more information about each image. Here's an example:
test.tif
test.tif.thing
If I'm converting to a format like png, I want to rename test.tif.thing to test.png.thing. Here's the existing script I have, which doesn't work at all due to me experimenting with numerous options, but it should hopefully highlight the problem:
for %%q in (*.tif.thing) do (
ren "%%q" "%%~pq%%~nq"
)
timeout 100
The main issue I'm having is removing the ".tif" when renaming the file, since ".thing" is technically the actual extension, so the filename is "thing.tif" without the extension. I looked into using variables to remove the characters from the string, but I never managed to get them to work, and if possible I'd like to know a cleaner solution to make this scale better should the filenames change in the future. How can I do this?
Use a second level of FOR to remove the inner extension from the file name
for %%A in (*.tif.thing) do (
REM %%A is filename.tif.thing
REM %%~nA is filename.tif
for %%B in ("%%~nA") do (
REM %%~nB is filename
ECHO ren "%%~A" "%%~nB.png.thing"
)
)
The ren command is disarmed to prevent actual renaming of files while testing the script. Remove ECHO to enable renaming.

Merge text files with the same name from all subdirectories and preserve others (deleting duplicate lines)

Hi I've got the following code (Windows), that is working quite well when all directories contains all the files and each one gets its correspondant matching name.
#echo off
for /r "." %%a in (*.txt) do (
echo %%~na
type %%a >> %%~na-merged.txt
for /f "delims=" %%I in (%%~na-merged.txt) do findstr /X /C:"%%I" %%~na.txt >NUL ||(echo;%%I)>>%%~na.txt
del %%~na-merged.txt
)
Well, my problem is that I have 100thoursands of txt files, named with prefix+date in several directories, some of those having matching names, some others not. My target is to group/consolidate them per name and put all in a common folder.
It's quite done, but I'm missing how to set the if/else condictions in dos.
Thx
EDIT: I've furtherly tested the code above and it seems now working very well. The problem is only with filenames containing whitespaces. So need only to do a massive rename before running it. I close the issue, btw any further comment is appreciated.

Delete semi duplicate files

I'm wondering if there is a way to remove semi-duplicate files (name based) using a batch file or any other means (freeware utility) in Windows?
To give an example I have following files in a directory:
fileNameXXX(aaa).ext
fileNameXXX(bbb).ext
In this case, I only want to keep the fileNameXXX(bbb).ext
it's a single line in batch:
for /f "delims=" %%f in ('dir /b "*(*).ext" ^| find /v "(ddd)"') do ECHO del "%%f"
For every file matching the filemask excluding files with (ddd) do: delete it.
Remove the ECHO if the output fits your needs.
Note: if you want to use it directly on command line (instead in a batch file), replace every %%f with %f.
Tip: think about using some more code to check, if there is a Dutch version, and if not, keep the English one (or whatever you prefer).

Batch read and rename from text file issue?

I'm a beginner with .bat files, and I'm attempting to rename multiple drawing (.dwg) files using a list generated in notepad. The notepad list contains a list of drawing numbers that look like this:
01013-13000p001
06301-12550p001
etc..
There is hundreds of them, and I want to take those numbers from the text and put it into a blank series of dwg files that are generic named for now (drawing.dwg, drawing(2).dwg, drawing(3).dwg etc..) I've only come up with a way to read a text file, but cant figure out how to take from the text file and rename multiple drawing files with it. Below is as far as I have gotten, after failed attempts of trying to take whats read from a text file and put it into the .dwg files. I plan on working this out in all the same directory, and any suggestions will be greatly appreciated. Thanks.
#echo off
for /f "tokens=* delims=" %%x in (dwgNumbers.txt.txt) do echo %%x
pause
would
for /f "delims=" %%x in (dwgNumbers.txt.txt) do echo copy /b "blank generic drawing.dwg" "%%x.dwg"
(as a batch line) do what you want? - note that the ECHO keyword is there to show what would be done. The echo keyword needs to be removed to actually execute the copy.
This will take the numbers from .txt, renaming the existing .dwg files with the data readed. If there are more files that numbers in .txt, it will rename until number exhaustion, no more.
for loop is using a dir command to get the list of files to avoid the case of files that after being renamed falls under the filter of the for and gets reprocessed.
This code has a echo command included in rename line to prevent data loss in case of malfunction. When the output to console is what is needed, remove the echo command from the rename line.
#echo off
rem Prepare environment
setlocal enableextensions enabledelayedexpansion
rem Read input file for numbers
< dwgNumbers.txt (
rem Process dwg files in directory
for /f "tokens=*" %%f in ('dir /b *.dwg') do (
rem Get number from input file
set "number="
set /p "number="
rem If there is a number, rename the file
if defined number echo ren "%%~f" "!number!.dwg"
)
)
rem Clean
endlocal

Resources