I'm trying to write a simple batch script to use identify (from ImageMagick) to check dimensions of files in this directory and decide its orientation. Later, I'll be adding moving them to seperate folders.
The problem is it can't enter the for loop.
setlocal enabledelayedexpansion
#echo off
for /r %%F in (*.) do (
identify -format "%%w" %%F > temp.txt
set /P temps=<temp.txt
set /A w=%temps%
identify -format "%%h" %%F > temp.txt
set /P temps=<temp.txt
set /A h=%temps%
if /I "%w%" GEQ "%h%" echo Is Landscape
if /I "%w%" LEQ "%h%" echo Is Vertical
pause
)
pause
You can make identify tell you the width and height in a single call for all files in the directory, rather than calling it twice for each and every file:
identify -format "%w %h %f\r\n" *.png
1024 768 a.png
10 10 b.png
So, you can pair that up with your script and do it this way faster and more succinctly:
#ECHO OFF
REM Get dimensions and names of all files in one go
FOR /F "tokens=1-3 delims=+" %%A in ('identify -format "%%w+%%h+%%f\r\n" *.png') DO (
REM %%A is width, %%B is height, %%C is name
ECHO %%A,%%B,%%C
)
Related
i am making a file selector which would randomly copy files from one folder to another code works quite fine but sometimes it shows The system cannot find the path specified for all or majority of files i don't know what went wrong can please someone help
my code
#echo off
setlocal enabledelayedexpansion
set num=0
cls
set /p input= enter the number of files you want:
set /p address= enter the address of your files:
md SelectedFiles
pushd "%address%" || goto :EOF
set /a num=%num%+1
for /f "tokens=1,* delims=[]" %%i in ('dir /b /s /a-d ^| findstr /RV "[.]jpg [.]png" ^| find /v /n ""') do (
set "file%%i=%%~j"
set "cnt=%%i"
)
for /l %%c in (1,1,%input%) do (
set /a rand=!random! %% !cnt!
for %%r in (!rand!) do copy "!file%%r!" "%address%\SelectedFiles" | clip
)
echo your files have been copied
pause
popd
Try, as a replacement for your for /l loop
for /l %%c in (1,1,%input%) do (
set /a rand=1 + !random! %% !cnt!
for %%r in (!rand!) do (
copy "!file%%r!" "%address%\SelectedFiles" | clip
for %%s in (!cnt!) do set "file%%r=!file%%s!"
set /a cnt-=1
)
)
Your filenames are currently being assigned to file1..file!cnt!.
You are then generating rand as 0..cnt-1, so there is a probability that you will choose file0 which does not exist and no possibility of choosing file!cnt!
There is also a possibility of re-choosing a file.
You should make sure that input is not greater than cnt.
My suggested code simply makes the range 1..cnt, then when a file has been processed, moves the very last filename (file!cnt!) over the chosen name and reduces cnt since there is one fewer filename in the list.
NOTE: Since the |clip is piping from a copy statement for one file only, it should only ever generate 1 file(s) copied. on the clipboard
EDITE: I have more than 100 file
I have multiple files that I want to rotate every time I run a batch.
How to do it in every SUB-FOLDER?
Here's the concept
Please help. Thanks.
#echo off
setlocal enabledelayedexpansion
REM get number of files:
set count=0
for %%a in (*.jpg) do set /A count+=1
REM rename them (decreasing by one):
for /l %%a in (1,1,%count%) do (
set /a new=%%a-1
ECHO ren %%a.jpg !new!.jpg
)
REM rename 0 to max
ECHO ren 0.jpg %count%.jpg
remove the ECHOs when you verified it's what you want.
I am try to get the width and height of some 50 images as variable and then with that variable trying to resize one particular image making 50 copies with those dimensions.
Below code is only giving single image output. Kindly help.
setlocal enabledelayedexpansion
%~d1
CD "%~p1"
MD small
FOR %%a in (*.jpg) DO (
identify -format "%%w" imageA.jpg > w.txt
set /p w=<w.txt
identify -format "%%h" imageA.jpg > h.txt
set /p h=<h.txt)
FOR %%a in (*.jpg) DO (
convert imageA.jpg -resize %w%x%h%! small\%%a
)
)
I did some work around to the code and I am able to get copies of images with names in the specified folder, but dimension are not applied. how to fix this?
setlocal enabledelayedexpansion
%~d1
CD "%~p1"
MD small
FOR %%f in (*.jpg) DO (
set filename=%%f
identify -format "%%w" %%f > w.txt
set /p w=<w.txt
identify -format "%%h" %%f > h.txt
set /p h=<h.txt)
FOR %%f in (*.jpg) DO (
set filename=%%f
convert imageA.jpg -resize %w%x%h%! small\%%~nxf
)
)
I have a list of 25 websites in a text file, each on an individual line, I would like to open them in random order via a batch file.
websites.txt
...
google.com
facebook.com
...
I know I need to use a for loop, but am not sure how to pull the website address from a random line. I thought of using...
for /f "tokens=%rannum%"
but all the websites would have to be on the same line and from my testing that did not work well. There would also need to be a way to make sure the same website is not opened twice.
What I have so far...
#echo off
set file=openweb.txt
set /a total_lines=1
for /f %%a in ('Type %_File%^|Find "" /v /c') Do Set /a total_lines=%%a
set /a start_count=0
set "found=found.txt"
if exist "%found%" del "%found%"
copy NUL found.txt
if %start_count% NEQ %total_lines% (
:run_again
REM Randomly select a number between 1-26
set /a random_number=%random% %% 26-1
REM Validation Random number was not used already
findstr /m "%random_number%" %found%
if %errorlevel%==0 (
echo already found
goto:run_again
)
REM Open each website. Wait 2sec between each.
for /f %%a in (websites.txt) do (
start iexplore %%a
#ping 127.0.0.1 -n 2 -w 1000 > nul
)
REM write out Random Number to the .txt
#echo %random_number%>>%found%
set /a start_count+=1
)
Any input on how to make this code better is welcome. Thank you
Try this:
#echo off
set file=openweb.txt
set /a lines=25
set /a skip=%random%%%lines%-1
more %file% +%skip% > temp.tmp
set /p target=< temp.tmp
del temp.tmp
Echo %target%
I have cracked my head up...
Now I have a folder containing empty subfolders and pictures.
These pictures are randomly named as their default name generated by the camera.
If I want to sort these pictures out into a few batches and then move them into the subfolders
For example:
lets say in total I have 100 pictures and five 5 subfolders.
first 20 pictures into subfolder_1
subsequent 25 pictures into subfolder_2
subsequent 23 pictures into subfolder_3
subsequent 12 pictures into subfolder_4
lastly the remaining 20 pictures into subfolder_5
So, I am thinking of doing it in loops. and since the number of pictures are not constant, and I intend to prompt the user to define number of pictures to be moved each time.
The main thing that I couldn't figure out is that HOW DO I CONTROL THE NUMBER OF LOOPS TO BE DONE?
I know about using GOTO function to break a FOR loop. But I am not sure how to do it in my case.
In fact, I am now still stucked with this concept I currently have, where I tried to use a shorter FOR loop to contain an longer FOR loop like this:
(this is just to try for the first 20 pictures into subfolder_1)
FOR /L %%A in (1,1,20) Do (
FOR %%B in ("%dir_of_folder_which_contains_the_pictures_and_subfolders%\*") Do (
MOVE *.jpg subfolder_1
)
)
These codes don't work. Perhaps it has got to be using GOTO function? Can anyone help? THANKS ALOT..
#echo off
setlocal enableextensions enabledelayedexpansion
set "folder=%cd%"
rem For each of the present subfolders
for /d %%a in ("%folder%\*") do (
rem Count the number of remaining files
set "nFiles=0"
for /f %%b in ('dir "%folder%\*" /a-d /b 2^>nul ^| find /c /v ""') do set "nFiles=%%b"
if !nFiles! lss 1 goto :done
rem Ask the number of files to move
echo(
echo(There are !nFiles! files left. How many to move to %%a ?
set "nFiles=0"
set /p "nFiles="
set /a "nFiles+=0" 2>nul
rem Move the indicated number of files
if !nFiles! gtr 0 for %%c in ("%folder%\*") do if defined nFiles (
echo move "%%~fc" "%%~fa"
set /a "nFiles-=1"
if !nFiles! equ 0 set "nFiles="
)
)
:done
endlocal
exit /b
Not the most efficient code, but this is a basic skeleton to build from. The move command has been prefixed with a echo for testing. If the output to console is correct, remove the echo.
This type of problems may be solved in a better way with the use of data structures, like arrays or lists. For example:
#echo off
setlocal EnableDelayedExpansion
rem Initialize counters
set /A numFolders=0, numFiles=0
rem Save file names in an array
for %%a in (*.*) do (
set /A numFiles+=1
set "file[!numFiles!]=%%a"
)
rem Save folder names in a list
set "list="
for /D %%a in (*) do (
set /A numFolders+=1
set "list=!list! %%a"
)
rem Ask the user for the distribution
:askDistribution
echo There are %numFiles% files and %numFolders% folders
echo Enter the number of files for each folder (must sum %numFiles%)
echo Folders: %list%
set /P "distribution=Files: "
set total=0
for %%a in (%distribution%) do set /A total+=%%a
if %total% neq %numFiles% goto askDistribution
rem Distribute the files
set i=0
for %%n in (%distribution%) do (
rem Get current folder and shift the rest
for /F "tokens=1*" %%a in ("!list!") do (
set folder=%%a
set list=%%b
)
rem Move the files
for /L %%i in (1,1,%%n) do (
set /A i+=1
for /F %%i in ("!i!") do ECHO move "!file[%%i]!" !folder!
)
)
For further details, see: Arrays, linked lists and other data structures in cmd.exe (batch) script