batch find file extension - windows

If I am iterating over each file using :
#echo off
FOR %%f IN (*\*.\**) DO (
echo %%f
)
how could I print the extension of each file? I tried assigning %%f to a temporary variable, and then using the code : echo "%t:~-3%" to print but with no success.

The FOR command has several built-in switches that allow you to modify file names. Try the following:
#echo off
for %%i in (*.*) do echo "%%~xi"
For further details, use help for to get a complete list of the modifiers - there are quite a few!

This works, although it's not blindingly fast:
#echo off
for %%f in (*.*) do call :procfile %%f
goto :eof
:procfile
set fname=%1
set ename=
:loop1
if "%fname%"=="" (
set ename=
goto :exit1
)
if not "%fname:~-1%"=="." (
set ename=%fname:~-1%%ename%
set fname=%fname:~0,-1%
goto :loop1
)
:exit1
echo.%ename%
goto :eof

Sam's answer is definitely the easiest for what you want. But I wanted to add:
Don't set a variable inside the ()'s of a for and expect to use it right away, unless you have previously issued
setlocal ENABLEDELAYEDEXPANSION
and you are using ! instead of % to wrap the variable name. For instance,
#echo off
setlocal ENABLEDELAYEDEXPANSION
FOR %%f IN (*.*) DO (
set t=%%f
echo !t:~-3!
)
Check out
set /?
for more info.
The other alternative is to call a subroutine to do the set, like Pax shows.

Related

Win Batch: Help defining variable in a FOR loop

I made this script that finds all directories and echoes the directorie's name to a .txt file. The script is working but it ends up echoing only %A without any value. My script is below!
set /a count=0
setlocal EnableDelayedExtensions
FOR /D %%A in ("*") DO (call :sub)
endlocal
pause
exit
:sub
(echo [DIR] %%A)>>%count%.txt
set /a count+=1
The output in the .txt files is [DIR] %A.
Any idea how to fixe this? Thanks -David
First remark, you are using an invalid option for setlocal but that is probably just a typo.
The problem is that you are try to use a for-parameter where it cannot be used.
The rule is "A for-parameter can only be used within the command or command block () of a for loop"
Your subroutine is not within the command block of a for loop, but you can start a dummy for loop in the subroutine which will give you access to all available for-parameters.
set /a count=0
setlocal EnableDelayedExpansion
FOR /D %%A in ("*") DO (call :sub)
endlocal
pause
exit/b
:sub
For %%. in (.) do (echo [DIR] %%A)>>%count%.txt
set /a count+=1
You need to pass the parameter to the subroutine.
From https://www.informit.com/articles/article.aspx?p=1154761&seqNum=11 :
for %%f in (*.dat) do call :onefile %%f
exit /b
:onefile
echo Processing file %1...
echo ... commands go here ...
exit /b
As you've already enabled delayed expansion, there's no need to use a Call to a label, just do it within the loop.
#Echo Off
SetLocal EnableExtensions EnableDelayedExpansion
Set "count=0"
For /D %%G In (*) Do (
Set /A count += 1
(Echo [DIR] %%G) 1>"!count!.txt"
)
On this version, I've started at 1 instead of 0 for the first text file name, if you really want to start at 0, change line 3 to Set "count=-1"

Trouble with nested IF in cmd batch file

The batch file below intends to find all files that don't match the set pattern and delete them. However, it won't execute at all. Looks like there is syntax issue in the IF statement that I couldn't find.
SETLOCAL ENABLEDELAYEDEXPANSION
SET SHARE_FOLDER=\\blyfs01\teams$\Hadoop\Workday\
SET WKDAY_FNAME=WKDY_HADOOP_PTODATA
FOR %%F in ("%SHARE_FOLDER%*.*") DO ( SET FNAME=%%~nxF & IF !FNAME:~0,28!==!WKDAY_FNAME!_%date:~-4%%date:~4,2%%date:~7,2% ( #ECHO DO #DEL %%F) )
elzooilogico got it right. It literally is the quote that made it work!
FOR %%F in ("%SHARE_FOLDER%*.*") DO ( SET FNAME=%%~nxF & IF "!FNAME:~0,28!" NEQ "!WKDAY_FNAME!_%date:~-4%%date:~4,2%%date:~7,2%" (#ECHO #DEL %%F) )

Windows batch: Reset Variable

I am trying to collect first file from the directory then process the file. But at the second time when the running and processing the batch file I am unable to store the values in the variable for the file name
Below is the sample code:
for /R C:\abcde_efghij\ab_abcabca %%i IN (*.*) DO (
set filename=%%i
set newname=%filename:~14%
set transname=%filename:~25%
goto tests
)
:tests
echo %filename%
echo %newname%
echo %transname%
I am sure we have to use something called SETLOCAL but I am unable to make it in the above code.
Any Help!
You should avoid percent expansion inside of blocks, also FOR blocks, as the expansion only occours only once when the block is parsed.
for /R C:\abcde_efghij\ab_abcabca %%i IN (*.*) DO (
set filename=%%i
goto :tests # Get only the first file
)
exit /b
:tests
set newname=%filename:~14%
set transname=%filename:~25%
echo %filename%
echo %newname%
echo %transname%
exit /b
As #Stephan noted, you could also use delayed expansion inside blocks.
setlocal EnableDelayedExpansion
for /R C:\abcde_efghij\ab_abcabca %%i IN (*.*) DO (
set filename=%%i
set newname=!filename:~14!
set transname=!filename:~25!
goto :tests # Get only the first file
)

How to read from a .properties file using batch script

I have a requirement where i'd like to read values from a .properties file
my properties file test.properties content
file=jaguar8
extension=txt
path=c:\Program Files\AC
From the above file I need to fetch jaguar or anything after =
Please help me. Thanks
For /F "tokens=1* delims==" %%A IN (test.properties) DO (
IF "%%A"=="file" set file=%%B
)
echo "%file%"
hope this could help
#echo off
FOR /F "tokens=1,2 delims==" %%G IN (test.properties) DO (set %%G=%%H)
echo %file%
echo %extension%
echo %path%
Note that there is no space after %%H. Else this causes a space to be appended, to file paths for example, and will cause file not found errors when the variables from the property files are used as part of a file path.Struggled for hours because of this!
A solution with support for comments (# style). See comments in code for explanation.
test.properties:
# some comment with = char, empty line below
#invalid.property=1
some.property=2
some.property=3
# not sure if this is supported by .properties syntax
text=asd=f
properties-read.bat:
#echo off
rem eol stops comments from being parsed
rem otherwise split lines at the = char into two tokens
for /F "eol=# delims== tokens=1,*" %%a in (test.properties) do (
rem proper lines have both a and b set
rem if okay, assign property to some kind of namespace
rem so some.property becomes test.some.property in batch-land
if NOT "%%a"=="" if NOT "%%b"=="" set test.%%a=%%b
)
rem debug namespace test.
set test.
rem do something useful with your vars
rem cleanup namespace test.
rem nul redirection stops error output if no test. var is set
for /F "tokens=1 delims==" %%v in ('set test. 2^>nul') do (
set %%v=
)
output from set test. (see above):
test.some.property=3
test.text=asd=f
The most important parts are:
the for-loop with the eol and delims option and
the if-checks that both variables %%a and %%b are set.
What you do in the for-loop with the variable and its value is certainly up to you - assigning to some prefixed variables was just an example. The namespacing approach avoids that any other global variable gets overridden.
For example if you have something like appdata defined in your .properties file.
I'm using this to get rid of an extra config.bat and instead using one .properties file for both the java app and some support batch files.
Works for me, but certainly not every edge case is covered here, so improvements welcome!
Try this
echo off
setlocal
FOR /F "tokens=3,* delims=.=" %%G IN (test.properties) DO ( set %%G=%%H )
rem now use below vars
if "%%G"=="file"
set lfile=%%H
if "%%G"=="path"
set lpath=%%H
if "%%G"=="extension"
set lextention=%%H
echo %path%
endlocal
I know this is ancient post but I would like to expand on toschug's great answer.
If the path in the .properties file would be defined as %~dp0 or any other variable that needs to be expanded first before using it, I recommend doing it the following way:
In the .properties file:
path=%~dp0
In the batch file you can then use it the following way (the code is to be used between the two for(s) defining one <=> cleanup one):
if "!test.path!" NEQ "" (
echo Not expanded path: !test.path!
call :expand !test.path! test.path
)
echo test.path expanded: !test.path!
pause
:expand
SET "%~2=%~1"
GOTO :EOF
Don't forget to use (at the start of the batch file):
SETLOCAL ENABLEDELAYEDEXPANSION
you can try this:
#ECHO OFF
#SETLOCAL
FOR /F "tokens=1* delims==" %%A IN (test.properties) DO (
ECHO %%A = %%B
)
#ENDLOCAL

Batch Files: Processing files in alphbetical (Numerical maybe>) Order

I am currently trying to process a bunch of files with imagemagick
using a batch file in windows, they are all numbered numerically as
follows:
image00
image01,
image02,
...,
image010,
image011,
...,
image0100,
image0101
and so on, but when i try to process the file it wants to run though
image00, image01, image010, image0100, image0101, image0102 and so on.
my code is as follows
SETLOCAL EnableDelayedExpansion
SET COUNT=0
FOR %%a in (*.bmp) DO
(
IF !ERRORLEVEL!==0
(
SET TFILE=0!COUNT!
SET TFILE=Terrain!TFILE:~-4!.jpg
SET /A COUNT+=1
ECHO %%a >output.txt
convert %%a -compress LOSSLESS !TFILE!
)
)
is there any way i can make it so that it will process these files in order, for the time being i have a work-around but it means that i continually have to change some script files when the images are used later on. I would much rather have all of the files be the same 'Terrain' name with incrementing number following.
Thanks in advance guys!
you can probably create some more batch code to "sort" the numbers by order, however, since you can use imagemagick, i suppose you can also download other stuff. my suggestion is you can try and use GNU sort (in coreutils ). Then in your batch , do some thing like this
pseudocode :
for ... ( dir /b *bmp | gnu_sort -n ) do (
echo "do your stuff"
)
you could probably check whether the sort that comes with Windows has a numerical sorting option. (the last time i check it doesn't have this option).
You could rename the files to be image000 image001, image002, ..., image010,
You could split up the file name something like this:
#echo off
setlocal ENABLEDELAYEDEXPANSION
if not defined TRACE (
set TRACE=REM
)
%TRACE% On
for %%a In (data\*.*) do call :EachFile %%a
endlocal
goto :eof
:EachFile %%a
set Name=%~n1
#Echo %Name%
set NUm=%Name:~6,9%
set /a Num=Num+100000
#echo %Num%
echo ren %1 %~dp1Image%Num%%~x1
goto :eof
It's hard to find, because it's not really obvious from the documentation. The solution is to use the FOR command in combination with the dir command. I would do something like this:
#echo off
ECHO Listed in name order: %1
ECHO ------------------------------------------------------
FOR /F "tokens=*" %%G IN ('dir /b /o:n %1') DO echo %%G

Resources