Batch file to generate files - batch-file

Ok, I am trying to make a batch file to generate a series of files and folders, but can't find on how to do it.
My Idea:
FOR /f "Tokens=* delims=" %%I IN (export2.csv) DO call:create %%I GOTO:EOF
:create ECHO 1 >>%~pd0%1
But it didn't work at all.

Since I have no idea how your data file looks like it's hard to give good advice here, but your code could be cleaned up a bit:
set "filepath=%~dp0"
for /f "tokens=* delims=" %%I in (export2.csv) do call :create "%%I"
rem This is needed to avoid stepping into the subroutine again
goto :eof
:create
rem This will create an empty file instead of one that contains a single line with 1
copy nul "%filepath%%~1"
goto :eof
This won't create any directories, though. You can create those with md.

Figured it out a little bit ago and here is what I ended up with. It will generate both the path and create an empty file with the name of the file listed in the masterlist.csv.
Source Code
#ECHO OFF
CHDIR "%~dp0"
SET Count=0
ECHO/ Generating Necessary File, please Wait...
FOR /F %%A IN (Masterlist.csv) DO CALL:MKDIR %%A
EXIT /B
:MKDIR
SET /A Count+=1
SET "Path=%~dp1"
SET "File=%~nx1"
IF NOT EXIST "%Path%" MKDIR "%Path%
IF NOT EXIST "%Path%" CALL:ERROR "Path"
IF NOT EXIST "%Path%\%File%" ECHO/ >>"%Path%\%File%"
IF NOT EXIST "%Path%\%File%" CALL:ERROR
EXIT /B
:ERROR
IF NOT EXIST "Errorlog.csv" ECHO Error, Line Count>>Errorlog.csv
ECHO %~1, Line %Count%>>Errorlog.csv
A few example lines from Masterlist.csv
2006\MS06-003\Office2000\office2000-kb892842-fullfile-enu.exe
2006\MS06-003\Office2003\office2003-kb892843-fullfile-enu.exe
2006\MS06-003\Office2003\WinSec-MS06-003-009-P44333-outlook2003-kb892843-fullfile-enu.exe
2006\MS06-003\OfficeXP\officexp-kb892841-fullfile-enu.exe
2006\MS06-006\WindowsMedia-KB911564-x86-ENU.exe
2006\MS06-007\2003\WindowsServer2003-KB913446-x86-ENU.exe
2006\MS06-007\XP\WindowsXP-KB913446-x86-ENU.exe
2006\MS06-012\2003\office2003-KB905756-FullFile-ENU.exe
2006\MS06-015\2000\Windows2000-KB908531-x86-ENU.EXE
2006\MS06-015\2003\WindowsServer2003-KB908531-x86-ENU.exe

Related

Using a FOR loop to rename files with a datestamp. Getting error "A duplicate file name exists, or the file cannot be found."

I'm trying to write a batch file that will rename every .txt file in the folder it's in to include a date stamp in the name. I've got it echoing out exactly as it should but when I try the same thing with rename or xcopy I get "A duplicate file name exists, or the file
cannot be found."
I'm new to batch and I can't quite figure out what's going on here. Maybe a small syntax issue?
#echo off
setlocal enabledelayedexpansion
goto :main
:main
for /f "delims=" %%a in ('wmic OS Get localdatetime ^| find "."') do set dt=%%a
set YYYY=%dt:~0,4%
set MM=%dt:~4,2%
set DD=%dt:~6,2%
set HH=%dt:~8,2%
set Min=%dt:~10,2%
set Sec=%dt:~12,2%
set stamp=!YYYY!-!MM!-!DD!___!HH!:!Min!:!Sec!
echo !stamp!
echo.
FOR %%G IN (*.txt) DO (
echo going to rename %%~nxG
echo it will become !stamp!___%%~nxG
ren %%~nxG !stamp!___%%~nxG
echo.
)
pause
goto :eof
Because of your invalid filename characters, :, which, as already mentioned in the comments, is the reason for your error message, here's an example, replacing them with a .:
#Echo Off
SetLocal DisableDelayedExpansion
Set "stamp="
For /F "Tokens=1-6Delims=/: " %%A In ('""%__AppDir__%Robocopy.exe" : : /NJH /L"'
)Do If Not Defined stamp Set "stamp=%%A-%%B-%%C___%%D.%%E.%%F"
If Not Defined stamp GoTo :EOF
For %%A In ("*.txt")Do If "%%~xA"==".txt" (Echo(&Echo going to rename %%~nxA
Echo it will become %stamp%___%%~nxA&Ren "%%~nxA" "%stamp%___%%~nxA")
Pause
GoTo :EOF
Please note, you may need to consider some sort of filtering system to prevent any subsequent runs of the script from processing the same files, further increasing their names by another 24 characters.

Batchfile to rename files

Sadly I couldn't yet manage find a working solution but hopefully this time.
Long story short, we got a printer and we are currently unable to configure the scanfolder to our network drives. So I need a script to rename and move the files but keep them all.
As far as I managed to come I got a smart idea to move the files into a firstfolder to avoid that the files are overwritten. Next I need to either rename the files with a counter or move them and keep them all.
I choose the rename option since this seems more simple but I ran into one big issue.
I have no idea how I make it work. So what I'm trying is to first set the variable and do a first test calculation. Just for a first quick test. Now it already works for the first count but sadly it doesn't count up as hoped since he does the rename for all the files before increasing the value of the variable so only one file is renamed.
#ECHO off
::Defining Variables
setlocal EnableDelayedExpansion
SET N=0
ECHO %N% Hi Not rename
SET /a N=%N%+1
FOR /L %%A in (1,1,10) DO (
Echo !N! hi
RENAME "C:\Users\smorheng\Desktop\1\*.pdf" "Test.?????.!N!.*" | SET /a N=!N!+1
ECHO !N! Hi Not rename
timeout 3 /nobreak > nul
)
ECHO RENAME DONE
timeout 50 /nobreak > nul
About 20 Files are renamed to something like Test.1.pdf, Test.2.pdf .... Test.20.pdf and then moved to their destination.
The moving is not an issue but if I could manage to get this feature working I can adapt it to whatever I need.
You can simply move the files, but first check if the file exists in destination, if it does, rename it using a numeric value after the name. Here is something that might work. You just need to change source and destination folder below. The actual move will not occur as I added echo to the second last and last line to demonstrate what it will do, if it works, simply remove echo from both lines.
#echo off
setlocal enabledelayedexpansion
set "source=C:\Users\smorheng\Desktop\1\"
set "dest=D:\destination\folder"
set /a cnt=0
for /f "tokens=*" %%a in ('dir /S /B /A-D "%source%*.pdf"') do for /f "tokens=*" %%b in ('dir /B "%%a"') do if exist "%dest%\%%b" (
set "ext=%%~xa"
set "fname=%%~na"
if exist "%dest%\!fname!(!cnt!)!ext!" (set /a cnt=!cnt!+1)
set /a cnt=!cnt!+1
echo move "%%a" "%dest%\!fname!(!cnt!)!ext!"
) else echo move "%%a" "%dest%\%%b"
Also note, this will recursively move all files from within the directory tree, if you only want to go into the first directory, simply remove /S from the for loop which will then simply become dir /B /A-D "%source%*.pdf"
Edit
As for your for /L loop (mentioned in comment)
Rather have a label and permanently goto it after completed. Here is a simple example of something like that, copy it to a script and run it, see the result:
#echo off
:label
echo Hi, this will run every 6 seconds and print this line. (infinitely).
timeout 6>nul
goto :label
So technically you can do the exact same for your loop, for instance:
#echo off
:label
setlocal enabledelayedexpansion
set "source=C:\Users\smorheng\Desktop\1\"
set "dest=D:\destination\folder"
set /a cnt=0
for /f "tokens=*" %%a in ('dir /S /B /A-D "%source%*.pdf"') do for /f "tokens=*" %%b in ('dir /B "%%a"') do if exist "%dest%\%%b" (
set "ext=%%~xa"
set "fname=%%~na"
if exist "%dest%\!fname!(!cnt!)!ext!" (set /a cnt=!cnt!+1)
set /a cnt=!cnt!+1
echo move "%%a" "%dest%\!fname!(!cnt!)!ext!"
) else echo move "%%a" "%dest%\%%b"
endlocal
timeout 6>nul
goto :label
Try replacing "RENAME" to SET newname see if that helps?
EDIT or try a vbs script instead of a batch?
`Set objFS = CreateObject("Scripting.FileSystemObject")
strFolder="c:\test"
Set objFolder = objFS.GetFolder(strFolder)
For Each strFile In objFolder.Files
If objFS.GetExtensionName(strFile) = "jpg" Then
strFileName = strFile.Name
If InStr(strFileName,"XXXXXXX") > 0 Then
strNewFileName = Replace(strFileName,"XXXXX","YYYYY")
strFile.Name = strNewFileName
End If
End If
Next `

how to get the list of files from the directory one by one into a variable

I am new to Batch script,
by using the following code
setlocal enabledelayedexpansion enableextensions
set LIST=
for %%x in (D:\all_files\*.csv) do set LIST=!LIST! %%x
set LIST=%LIST:~1%
echo %LIST%
i am getting the filenames with directory and also with a Paragraph
but i need file names alone one by one like below into a Variable of %LIST%
file1.csv
file2.csv
file3.csv
can any one please help us
I hope, I got your intentions right.
Instead of a variable, just loop over output of dir /b
:loop
echo still waiting...
timeout /t 10
set "ok=yes"
for /f "delims=" %%a in ('dir /b "D:\all_files\*.csv"') do (
if not exist "C:\%%a" set "ok=no"
)
if "%ok%" == "no" goto :loop
echo all there...
call process1.bat

Search file with wildcard path

I want to write a script to prompt user for file path and list all files found. The file path can contain wildcards. Something similar to this. But the batch script version of it. For example:
C:\Somewhere\user*\app\version-*.*\start.exe
The files might be located like this:
C:\Somewhere\user345\app\version-1.0\start.exe
C:\Somewhere\user898\app\version-1.2\start.exe
C:\Somewhere\user898\app\version-1.3\start.exe
I tried to use FOR and it turns out to be so much harder than expected because FOR does not support wildcards in the middle of a path.
Is there a way to list these files? (Maybe without using for?)
I think this recursive solution works pretty well; you may name it WCDIR.bat:
#echo off
setlocal
if "%~1" neq "" set "next=%~1" & goto next
echo Show files selected by several wild-cards
echo/
echo WCDIR wildcardPath
echo/
echo Each folder in the path may contain wild-cards
echo the last part must be a file wild-card
goto :EOF
:next
for /F "tokens=1* delims=\" %%a in ("%next%") do set "this=%%a" & set "next=%%b"
if defined next (
for /D %%a in ("%this::=:\%") do (
setlocal
cd /D "%%~a" 2>NUL
if not errorlevel 1 call :next
endlocal
)
) else (
for /F "delims=" %%a in ('dir /B /A:-D "%this%" 2^>NUL') do echo %%~Fa
)
exit /B
EDIT: I fixed a small bug in the last for /F command.
For example, the output of WCDIR.bat C:\Windows\Sys*\find*.exe command in my Windows 8.1 64-bits computer is:
C:\Windows\System32\find.exe
C:\Windows\System32\findstr.exe
C:\Windows\SysWOW64\find.exe
C:\Windows\SysWOW64\findstr.exe
You can try with the command Where /?
The WHERE command is roughly equivalent to the UNIX 'which' command. By default, the search is done in the current directory and in the PATH.
#echo off
Where /R "%programfiles%" *winrar.exe
pause
#echo off
:: Example d'input
set UserInput=*drive*
:: building the Pattern
set cmd=%Userinput%.exe
:: storage Where.exe command in a macro, the execution will be faster
set whereCmd=where.exe /r c:\windows\ %cmd%
:: execution of macro and output formatting
for /f %%a in ('%whereCmd%') do echo %%~nxa --^> %%a
pause

Rename multiple files in a directory using batch script

I have about 1000 images and they have name like "IMG-12223". I want to rename them to 1 2 3 4 ... 1000. How can I do that. I have written a batch script which list the files but I don't know how to rename each file. e.g. rename first image with name "IMG-12223" to 1 , second image with name "IMG-23441" to 2 and so on ...
for /r %%i in (*) do (
echo %c%
)
Here's the script. Just put the script in your folder and run it.
#echo off & setlocal EnableDelayedExpansion
set a=1
for /f "delims=" %%i in ('dir /b *') do (
if not "%%~nxi"=="%~nx0" (
ren "%%i" "!a!"
set /a a+=1
)
)
If you want to keep the extensions, i.e. rename "IMG-12223.jpg", "IMG-12224.jpg", etc to "1.jpg", "2.jpg", etc, you may use the following script.
#echo off & setlocal EnableDelayedExpansion
set a=1
for /f "delims=" %%i in ('dir /b *.jpg') do (
ren "%%i" "!a!.jpg"
set /a a+=1
)
[Update] Here're explanations for the lines mentioned in Jack's comment.
setlocal EnableDelayedExpansion
In general, we want the variable a to be delayed expansion when it's executed but not the line is read. Without it, the variable a cannot get its increased value but always 1.
For the detail of EnableDelayedExpansion, please refer to the answer https://stackoverflow.com/a/18464353/2749114.
for /f "delims=" %%i in ('dir /b *.jpg')
Here dir with /b option, lists only file names of all jpg files.
The for loop traverses and renames all jpg files.
For the delims option, since the default delimiter character is a space, without the option delims=, it fails with the image files with spaces in the file names. I.E. for an image file named "img with spaces.jpg", without the option, the value of %%i is "img" but not the whole name "img with spaces.jpg", which is incorrect.
For for loop, please refer to the page http://ss64.com/nt/for_f.html.
if not "%%~ni"=="%~n0"
I have change it to if not "%%~nxi"=="%~nx0" to be more accurate. And the codes attached have been updated.
It's actually used to avoid to rename the bat file itself. If we limit the renaming only upon "jpg" files, then the line is not needed.
%%~nxi is the file name with extension for each file traversed. And %~nx0 is the running bat file with extension. For details, please refer to the page DOS BAT file equivalent to Unix basename command?.
There is no need for a batch script. A simple one liner from the command line can do the job :-)
I use DIR /B to generate the list of files, piped to FINDSTR to number the files, all enclosed withn FOR /F to parse the result and perform the rename.
for /f "delims=: tokens=1*" %A in ('dir /b *.jpg^|findstr /n "^"') do #ren "%B" "%A%~xB"
Double the percents if you want to put the command in a batch script.
Try this, you have pair of namevalues in a text file then loop values and do the magic. Namevalues are separated by empty spaces. This allows you to map old->new filenames accordingly. Or you keep idx+1 counter and use it for new filenames.
keyvalue.bat
#echo off
set idx=0
for /F "tokens=1,2" %%A in (keyvalue.txt) do call :PROCESS "%%A" "%%B"
GOTO :END
:PROCESS
set var1=%~1
set var2=%~2
set /A idx=%idx%+1
echo %var1% goes to %var2% (%idx%)
GOTO :EOF
:END
pause
keyvalue.txt
file888.dat newfile1.dat
file333.dat newfile2.dat
file9.dat newfile3.dat
file01.dat newfile4.dat

Resources