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.
Related
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
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.
I have a task to rename a file and place another file with same name in the same folder
Like for e.g. a folder C:/test I have multiple files .txt (suppose test.txt is the one needed rename and replace)
I want to rename test.txt to test_bkp%date% and place new file there.
Need help to start the logic.
#ECHO OFF
SET "sourcedir=C:\Users\test\new"
FOR /f "delims=" %%a IN (
'dir /b /a-d "%C:\Users\Test\new\%filenames%.txt" '
) DO (
SET "filename=%%a"
ECHO REN "%C:\Users\Test\new\%%a C:\Users\Test\new\%%a_bk_date.*%"
)
GOTO :EOF
Let me explain what I am trying to achieve. I get file with updated data often. I cannot just go ahead and replace the old file with new. I have to take a backup and place the new file in the folder.
This is my first try using batch scripting
As soon as you write a new version of a file into the same folder than the original (with the same name), it's already too late to rename the original - it doesn't exist anymore. You need two folders: one that receives new versions (new) and one where you keep your renamed files plus the new ones (old)
#ECHO OFF
setlocal
set "source=C:\Users\test\new"
set "destin=C:\Users\test\old"
set "files=*.txt"
REM for every matching file in the source folder:
for %%A in ("%source%\%files%") do (
REM if there is such a file in the destination folder, rename it:
if exist "%destin%\%%~nxA" ren "%destin%\%%~nxA" "%%~nA-%date%%%~xA"
REM only then copy the file:
copy "%%~fA" "%destin%\"
)
This will fail if you run it more than once per day. (More code needed to handle that; for example, adding time too)
It will also fail if your %date% contains characters that are not allowed in file names (my %date% looks like 29.01.2019). (More code needed to handle that; for example %date:/=-%)
So, I'm trying to convert a bunch of OGG files to M4A using a program called Super. Only problem is that this program adds the extension you're trying to convert to after the source extension.
So, if I convert a file named Keyboard.ogg to an M4A file, it converts it to an M4A, but the resulting file name is Keyboard.ogg.M4A.
What I want to do is when the conversion finishes, I want to run a command or batch script on every file ending in .ogg.M4A so that the result is Keyboard.m4a instead of Keyboard.ogg.M4A (The file extension should be lower case since a program I am using to develop a video game requires both .ogg and .m4a files for exports (since it uses OGG for PC exports and M4A for Mobile exports) and I think it might be case sensitive.)
I have tried the solution here, but when using %%~nf it only removes the .M4A part (instead of the .ogg.M4A) and if I were to rename that I'd be back at square 1.
Assuming none of your file names contain any additional dots other than .ogg.M4A, then all you need is a single REN command.
ren *.ogg.M4A ??????????????????????????????.m4a
Be sure to use enough ? to match the longest name in your file set.
See How does the Windows RENAME (REN) command interpret wildcards? for a full explanation of how REN handles wildcards.
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
FOR /f "tokens=1*delims=" %%a IN (
'dir /b /a-d "%sourcedir%\*.ogg.M4A" '
) DO (
FOR %%b IN ("%%~na") DO (
ECHO REN "%sourcedir%\%%a" "%%~nb.m4a"
)
)
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
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.
Take the name of each file in the source directory that fits the mask "*.ogg.m4a"
Using the name part of the filenamename, rename using the name part only +the required extension.
Firstly I've tried looking everywhere, and was unsuccessful. I am inexperienced and appreciate any help at all. I'm trying to write a script to drag a folder onto a batch file, which will then convert all images in that folder to jpgs, using ImageMagick. I can see it's very possible to execute the script on the command line, that all works fine. But to drag a folder is giving me issues. I can drag many files onto the script and it converts fine:
convert %* %1.jpg
that works great. I can also drag a folder, and it will convert the images inside, but rename then as the name of the folder, one directory higher, like so:
#set SOURCE=%1
convert %SOURCE%\* %SOURCE%.jpg
I imagine i need a for loop performing the convert on every file in the folder. But I have run into problems. I'm unsure where to put quotes, and what variables to use, and how to overcome spaces. I imagine something like this...
for %%f in (%SOURCE%\*) do ( convert %%f "%SOURCE%\%%f.jpg" )
But yeah, I'm at a loss. I'm trying this little project both to learn, and also to help my dad convert large amounts of his photos quickly.
It sounds like ImageMagick can take multiple input arguments and one output argument, but to simplify it with one file at a time try the following. Your loop looks right but the ~ changes below will handle quotes.
You may also want to change the %%a* match to be particular files so you don't catch existing jpgs or non-image files, e.g. for %%f in (%%a*.png %%a*.gif) do ...
Finally, add an "echo" in front of the two convert lines so you can do a test run.
#echo off
rem Loops through arguments. If a file converts it to a jpg. If a directory
rem converts files in that directory to jpgs. Assumes a program "convert".
set count=0
for %%a in (%*) do (
if exist %%a (
if exist %%a\ (
rem Directory, loop through contents
for %%f in (%%a\*) do (
convert "%%f" "%%~a\%%~nf.jpg"
set /a count+=1
)
) else (
rem File, just convert
convert "%%~a" "%%~na.jpg"
set /a count+=1
)
) else (
echo Skipping non-existent %%~a
)
)
echo Converted %count% files
pause
Not quite what you want; this creates a new directory within the original directory to save the modified photos into:
:: Create the new directory
md %1\resized
:: Resize and save the new version
for %%f in (%1\*.jpg) do ( convert "%%f" -thumbnail 800x800 "%1\resized\%%~nf.jpg" )