Trouble with nested IF in cmd batch file - windows

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) )

Related

Batch script - dynamic/variable paths in loop

My requirement is to write a batch script to find and replace the a string in all of the *-spec.js files in given set of directories. Hence I have written the batch file and running the batch script as below.
<script file name> <search_string> <replace_string> <folder_path_1> <folder_path_2> <folder_path_n>
(I am sure the folder_path_n will not go beyond 7)
e.g C:\CI\Scripts>replace.bat hello world C:\app\e2e C:\sppa\e2e
So my script is as below.
#echo off
setlocal enabledelayedexpansion
set argCount=0
for %%x in (%*) do (
set /A argCount+=1
set "argVec[!argCount!]=%%~x"
)
set search=%1
set replace=%2
echo Search is %search%
echo Replace is %replace%
for /L %%i in (3,1,%argCount%) do (
set path=!argVec[%%i]!
echo path is !path!
for /R !path! %%F in (*spec.js) do (
echo %%F
)
)
Here it prints the 4 arguments correctly even the path is also printed as expected. In the next step it's expected to loop through the given path and gets all of the files that ends with "spec.js".
e.g not working:
for /R !path! %%F in (*spec.js) do (
echo %%F
)
But it prints nothing. Instead if the variable is replaced with hard coded value, it works as expected.
e.g - working:
for /R C:\app\sppa\e2e %%F in (*spec.js) do (
echo %%F
)
Your help is highly appreciated!
The reason it's not working is that the variable content must be known when the loop is parsed means that it only works with variables that can be expanded without delayed expansion. Nevertheless there is an easy solution as a for /r loop is working with the current path (from ss64).
If the [drive:]path are not specified they will default to the current drive:path.
Just change directory to !path! and then go back:
rem Change into !path! and remember directory coming from
pushd !path!
for /R %%F in (*spec.js) do (
echo %%F
)
rem Change back to origin
popd
I also tried similar as suggested by #Andre Kampling as below.
cd !path!
::echo Changed the path to !path!
FOR /R %%F IN (*spec.js) DO (
echo %%F
)

Read directories and split path

To list the directories I use this:
set folder=C:\temp
for /d %%a in ("%folder%\*") do (
echo %%~fa
)
To splith the file path I use this:
for %%f in (%MYDIR1%) do set myfolder=%%~nxf
echo %myfolder%
Now I want put both together:
#echo off
set folder=C:\Windows
for /d %%A in ("%folder%\*") do (
for %%d in (%%~fA) do set lastfolder=%%~nxf
echo %lastfolder%
)
All I get in thes result is %~nxf. I tried some things, but I didn't get a correct result. What I'm doing wrong?
What I don't understand in these examples is %~fA and %~nxf. Don't know where you can look up things like this.
Edit:
%~nxf to get file names with extensions
where F is the variable and ~n is the request for its name | Source
%~fI Expands %I to a fully qualified path name.
Now I modified my code with the new information:
#echo off
for /d %%A in ("%folder%\*") do (
for %%D in (%%~fA) do (
set lastfolder=%%~nxD
echo %lastfolder%
)
)
Now I get as result the last folder, but this is printed as many times as subfolders are existing. So I only get the last one. How can I iterate over each?
Solution:
Thanks to bgalea this is my solution:
#echo off
setlocal enabledelayedexpansion
set folder=C:\Windows
for /d %%A in ("%folder%\*") do (
for %%D in (%%~fA) do (
set lastfolder=%%~nxD
echo !lastfolder!
)
)
endlocal
Things in bracket are one line. Therefore you have to use !var! which you turn on with setlocal enabledelayedexpansion. See set /? and setlocal /?.
. is current directory and .. is parent directory.
So c:\temp\.. is the same as c:\
%~nx1 etc are documented in the call command's help - call /?
My answer here Trouble with renaming folders and sub folders using Batch has a list of command prompt punctuation.

Replace "." to "_" in folders using CMD

As can be seen in the image I have folders with "." in them I would like to replace these with a "_" using CMD is there a method to do this.
cmd.exe shell scripting is the worst approach for anything more than #echo off :-)
But ok.
You can use the enhanced shell command set to replace characters in a variable:
set DUH=FBB
echo %DUH:B=O% -> FOO
So, for your problem, you need to read all folders and get them in a variable, so you can replace .=_ and then rename.
First batch: rena.cmd iterates over your folders
#echo off
for /D %%i in ( *.* ) do call rena2.cmd %%i
Second batch: rena2.cmd handles the rename
#echo off
setlocal enableextensions
setlocal enabledelayedexpansion
set TONAME=%~1
move %1 "%TONAME:.=_%"
exit /B
This can be done in one script, feel free to fiddle it together, I won't :-)
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir\t w o"
FOR /f "delims=" %%a IN (
'dir /b /ad "%sourcedir%\*.*" '
) DO (
SET "dirname=%%a"
SET "dirname=!dirname:.=_!"
IF "!dirname!" neq "%%a" ECHO(REN "%sourcedir%\%%a" "!dirname!"
)
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.
Dimply perform a directory-list, change the . to _ and if a change was made, perform the rename.

Remove Last Characters from my filenames in windows

Im quite new to batch programming and i wanted to remove the last characters on my filename.
10_myfile_12345_6789.txt
11_myfile_12345_0987.txt
I want to remove the last 4 digits on my filename how i could do that?
I have tried this
#echo off
setlocal enabledelayedexpansion
set X=3
set FOLDER_PATH=
pushd %FOLDER_PATH%
for %%f in (*) do if %%f neq %~nx0 (
set "filename=%%~nf"
ren "%%f" "!filename!%%~xf"
)
popd
PAUSE
but it removes on first and last characters, i only saw this here too, im still quite confused how this works
With your recent clarification - I would do the following.
#echo off
setlocal enabledelayedexpansion
set FOLDER_PATH=C:\Some\Path\
for %%f in (%FOLDER_PATH%*) do if %%f neq %~nx0 (
set "filename=%%~nf"
ren "%%f" "!filename:~0,-4!%%~xf"
)
PAUSE
This will change your examples
10_myfile_12345_6789.txt
11_myfile_12345_0987.txt
Into
10_myfile_12345_.txt
11_myfile_12345_.txt
If you want to remove the trailing _ simply change !filename:~0,-4! to !filename:~0,-5!. This is simple string manipulation.
::working script to rename + remove suffix
::fixed problem file is not found while rename.
#echo off
set /a count = 0
for %%i in ("*.ts") do (set fname=%%i) & call :rename
goto :eof
:rename
::template name ==> names__1xxx.ts
::to rename the begin change zero to something
set name=%fname:~0,-8%
set /a count=count+1
::by random or count i bypass the problem of file not found while rename
ren "%fname%" "%name%_%count%.ts`
Results :
before : names__1xxx.ts
after : names__1.ts

batch find file extension

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.

Resources