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" )
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'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.
I need to move files from one Dir to another while placing the files in sub-directorates according to their file name.
Background:
File name (building Number)-assign-flr-pln.dgn
new location would be F:/Assignment Floor Plans/Buildings/(Building Number)/floor plan file.
The batch files needs to read the .dgn name for the building number then place the file in the corresponding floor plan sub folder in the building number folder
so...
take (building number)-assign-flr-pln.dgn file from one dir and place it.....
Assignment Floor Plans
- Buildings
-(building number)
-Floor Plan Files <-- Here
You have a fair bit to learn if you want to do something this complicated directly from a batch file.
Research list:
FOR
SET
CALL
You'll want to use the FOR command to get the filename; pay attention to the %~ options. For example:
set BAT_DGNFNM=
for %%F in (*.dgn) do set BAT_DGNFNM=%%~nF
This causes the environment variable BAT_DGNFNM to be set to the base filename. However, it loops through all the files, so really, you need it to call a subroutine for each file:
for %%F in (*.dgn) do call :DODGN "%%~dpnxF" "%%~nF"
This calls the subroutine :DODGN and passes it two quote-encapsulated parameters; the first one is the fully-qualified filename and the second one is simply the base filename.
Then you do the actual file handling in the subroutine:
:DODGN
set BAT_DGNFNM=%1
set BAT_DGNBNM=%2
REM Do stuff with BAT_DGNBNM using SET commands
GOTO :EOF
You'll need to make sure you don't "fall through" to the subroutine after the main loop is done, and you should clean up your environment variables when you're done, so this would look something like:
#echo off
for %%F in (*.dgn) do call :DODGN "%%~dpnxF" "%%~nF"
goto ENDIT
:DODGN
set BAT_DGNFNM=%1
set BAT_DGNBNM=%2
REM Do stuff with BAT_DGNBNM using SET commands
GOTO :EOF
:ENDIT
set BAT_DGNFNM=
set BAT_DGNBNM=
Good luck -- this stuff can get complicated.
Final reminder: Most of your learning curve will be with the SET command -- that's how you extract substrings out of one environment variable and put it into another, perform text replacement, etc.
This stuff is way easier in VBS or PowerShell.
Although you showed no code we could help you with...
It's quite easy if you know the commands to use (a great site for starters:
SS64):
Use a plain for loop to get each file.
Use a for /f loop to extract the building-nr (according to your comment it's the first token separated by a dash)
Use md to create the destination folder (ignore error if already existent)
Use copy to copy the file.
Finished.
#echo off
REM prepare some files for testing:
break>100-assign-flr-pln.dgn
break>110-assign-flr-pln.dgn
break>235-assign-flr-pln.dgn
REM now copy them into their destination folders:
set "dest=Assignment Floor Plans - Buildings - # - Floor Plan Files"
for %%f in (*-assign-flr-pln.dgn) do (
for /f "tokens=1 delims=-" %%a in ("%%f") do (
call md "%%dest:#=%%a%%" 2>nul
call copy "%%f" "%%dest:#=%%a%%\"
)
)
REM now show the result:
tree /f
Note: adapt your destination (add F:\)
"Special Effects":
call <command>: introduce another layer of parsing to avoid delayed expansion
#=%%aString replacing within a variable
2>nul suppress error messages
I have created a .bat using Image Magick's 'convert' command to convert color profiles for .jpgs. The conversion works correctly however, the converted .jpg files are moved from source path to path of the .bat script.
#echo off
setlocal enabledelayedexpansion
set IMCONV="C:\Users\%username%\Desktop\Color_Check_v1.5\_Data\conversion_script\convert.exe"
Path C:\Users\%username%\Desktop\Color_Check_v1.5\_Data\conversion_script\
FOR %%f IN (C:\Users\%Username%\Desktop\Color_Check_v1.5\_Upload\*.jpg) DO (
%IMCONV% %%f -profile "C:\Users\%username%\Desktop\Color_Check_v1.5\_Data\color_profile\sRGB_Color_Space_Profile.icm" %%~nf.jpg
)
I am unable to find a solution other than adding a second command to move the converted .jpgs back to source folder & replace the non-converted .jpgs. I wish to avoid this second command.
move /y "C:\Users\%Username%\Desktop\Color_Check_v1.5\*.jpg" "C:\Users\%Username%\Desktop\Color_Check_v1.5\_Upload" >nul
Any thoughts on how to execute the script to replace the old .jpgs with the newly converted .jps in the source folder?
Please make backup first and then try the following two suggestions.
Use mogrify instead of a loop
mogrify -profile xyz.icm "C:\Users\%Username%\Desktop\Color_Check_v1.5\_Upload\*.jpg"
Use a loop, but change the output filename
FOR %% IN ... DO (
convert %%f -profile xyz.icm %%f
)
I have an .exe file that takes two parameters when i run it from the command line, as such:
test_app.exe -vid.avi -data.txt
How would i be able to START the .exe file through a batch script and pass it those parameters?
If i have multiple .avi and .txt files that i need to pass to the .exe file through START, how would i be able to have a variable that goes through all of those files two at a time? (pairing every .avi with it's correspondant .txt).
Let's assume that every pair of .avi and .txt share the same name but obviously have different extensions.
I need to write something like this:
#ECHO OFF
START test_app.exe -vid.avi -data.txt
pause
But the parameters should be variables that increment every time a pair of parameters are proccessed through the .exe so it would loop on all of the files in the CWD.
Trying to do this but seems like START does not work that way?
#echo off
for %%a in (*.avi) do (
START Tester.exe -%%a -%%~na.txt
)
pause
try this, it works with AVI as the main extension, you may change this:
#echo off &setlocal enabledelayedexpansion
for %%i in (*.avi) do (
set "line="
for %%j in ("%%~ni.*") do set line=!line! -"%%~j"
start "" test_app.exe !line!
)
Try this with your avi files. It will just echo the bunch of commands and you can see what it does. The - signs seem a bit odd but I included them with the names.
#echo off
for %%a in (*.avi) do (
echo exe.file "-%%a" "-%%~na.txt"
)
pause