I recently asked you guys some help for a double conditions in batch file. You guys helped me very well but I'm now struggling with a new trouble... I'm trying to optimize my script.
Previous question (How to double conditions in batch file?)
I would like to list all files with the .doc extension that are in the subfolders named on the current date only. I think I'm making a mistake on the use of this double loop.
#echo off
chcp 1252
set Pathname="D:\testDir"
set year=%date:~-4%
set month=%date:~-7,2%
set day=%date:~-10,2%
set logfile=%Pathname%\logs\log.txt
cd %Pathname%
d:
for /D /R %%i in (*%year%_%month%_%day%*) do (
for /R %%i %%s in (*.doc) do (
echo "file : %%s worked and does an output at %time%" >> %logfile%
)
)
Can you give me a little help? Thanks for your help and advices.
EDIT: I need to perform actions on each .doc file in folders containing the string YEAR_MONTH_DAY. But the .doc files can also be located in other subdirectories.
It could be something like that :
D:\testDir\directory1_2021_11_16\test.doc
D:\testDir\directory1_2021_11_16\test.log
D:\testDir\directory1_2021_11_16\subDirectory1\test.doc
D:\testDir\directory1_2021_11_16\subDirectory1\test.log
D:\testDir\directory1_2021_11_17\test.doc
D:\testDir\directory1_2021_11_17\test.log
D:\testDir\directory1_2021_11_17\subDirectory1\test.doc
D:\testDir\directory1_2021_11_17\subDirectory1\test.log
D:\testDir\directory1_2021_11_17\subDirectory2\test.doc
D:\testDir\directory1_2021_11_17\subDirectory2\test.log
D:\testDir\directory1_2021_11_17\subDirectory2\subSubDirectory1\test.doc
D:\testDir\directory1_2021_11_17\subDirectory2\ubSubDirectory1\test.log
D:\testDir\directoryThatIDontCare\test.doc
D:\testDir\directoryThatIDontCare\test.log
D:\testDir\directoryThatIDontCare\subDirectory1\test.doc
D:\testDir\directoryThatIDontCare\subDirectory1\test.log
Any solutions ? Thanks for your time guys !
Here's an example script you can learn from, and run, to achieve what your submitted code was intending to do.
#Echo Off
SetLocal EnableExtensions
Set "CurDate="
For /F "Delims==" %%G In ('"(Set _) 2>NUL"') Do Set "%%G="
For /F "Delims=" %%G In ('%SystemRoot%\System32\wbem\WMIC.exe Path
Win32_LocalTime Get Day^, Month^, Year /Format:List
2^>NUL') Do For /F "Tokens=*" %%H In ("%%G") Do Set /A "_%%G + 10000"
For /F "Tokens=1,* Delims==" %%G In ('"(Set _) 2>NUL"') Do (
SetLocal EnableDelayedExpansion & If %%H Gtr 10059 (For %%I In (!%%G:~-4!
) Do EndLocal & Set "%%G=%%I") Else For %%I In (!%%G:~-2!
) Do EndLocal & Set "%%G=%%I")
Set CurDate=%_Year%_%_Month%_%_Day%
For /F "Delims==" %%G In ('"(Set _) 2>NUL"') Do Set "%%G="
If Not Defined CurDate GoTo :EOF
Set "BaseLocation=D:\testDir"
PushD "%BaseLocation%" 2>NUL || GoTo :EOF
Dir "logs" /B /A:D 1>NUL 2>&1 || (MD "logs\%CurDate%" 2>NUL || GoTo :EOF)
Set "LogFile=%BaseLocation%\logs\log.txt"
For /F "EOL=? Delims=" %%G In ('Dir "*_%CurDate%" /B /A:D 2^>NUL'
) Do For /F Delims^= %%H In ('Set "PATHEXT^=" ^& %SystemRoot%\System32\where.exe
/F /R "%%G" "test.doc" 2^>NUL'
) Do (Echo file : %%~H worked and does an output at %TIME%) 1>>"%LogFile%"
If you want to know how any of it works, please use the built-in help information for each command, use the site search facility and/or your chosen search provider. I am not a private tutor, so will not be performing such a role.
Related
Thanks in advance for any help given.
After searching through all relative threads and google search I'm stumped on finding a solution to output a variable name for merging two PDF's.
So I have 100's of PDF's I need to combine (two at a time) in a folder c:/test
The files are set out like below
Company Name Invoice No 123456
Company Name Invoice No 123456 details
Now I have managed to move two files at a time to a different folder and merge them but can't seem to get the desrired output name I'm after which is to put a week ending date in front (or at the end, not fussed) of the first merged filename. Below is the code I have thus far which works but the output file name is blank but gets created.
Very new to batch scripting and would appreciate any help :)
#echo off
setlocal enableextensions enabledelayedexpansion
set pdftk=C:\Program Files (x86)\PDFtk Server\bin\pdftk.exe
set Source=C:\test
set Target=C:\test\test2
set num=2
set filenumber=1
for /F "tokens=1,2 delims=:" %%f in ('dir /b /a-d "%source%\*.pdf" ^| findstr /n "^" ') do (
if %%f leq %num% (
copy "%source%\%%g" "%target%" /y > nul
) else goto endCopy
)
:endCopy
endlocal
for /F "tokens=1,2 delims=:" %%f in ('dir /b /a-d "%target%\*.pdf" ^| findstr /n "^" ') do (
if %%f leq %filenumber% ( set file=%%~nA
)
)
pdftk *.pdf cat output we_19_9_2017_%file%.pdf
In endCopy you are trying to get the name of A whereas you are iterating with f. Use set file=%%~nf to set the name of file or set file=%%~ng for second file.
And move endlocal at the end to expand !file! at the end of script like this (note the !):
:endCopy
set "cmd=dir /b /a-d "%target%\*.pdf" ^| findstr /n "^""
for /F "tokens=1,2 delims=:" %%f in ('%cmd%') do if %%f leq %filenumber% set file=%%~nf
pdftk *.pdf cat output we_19_9_2017_!file!.pdf
endlocal
Read more about DelayedExpansion at: https://ss64.com/nt/delayedexpansion.html
The last command doesn't use the target folder for the input files and thus looks for the input files in the current folder, so either include the path or first change to the target path.
Also you set a path-variable for pdftk but don't use it.
If this path isn't included in the %path% it can't be find.
Try this (untested)
#echo off
setlocal enableextensions enabledelayedexpansion
set "pdftk=C:\Program Files (x86)\PDFtk Server\bin\pdftk.exe"
set "Source=C:\test"
set "Target=C:\test\test2"
set num=2
set filenumber=1
for /F "tokens=1,2 delims=:" %%f in (
'dir /b /a-d "%source%\*.pdf" ^| findstr /n "^" '
) do if %%f leq %num% (
copy "%source%\%%g" "%target%" /y > nul
) else goto endCopy
:endCopy
endlocal
for /F "tokens=1,2 delims=:" %%f in (
'dir /b /a-d "%target%\*.pdf" ^|findstr /n "^" '
) do if %%f leq %filenumber% set file=%%~nf
PushD "%Target%"
"%pdftk%" *.pdf cat output we_19_9_2017_%file%.pdf
PopD
Everyday, a document is created automatically named articles.txt.
I have to make several changes to the document.
After the changes made the document is named articles_Final + date.txt
As example : articles_Final_2016_01_07.txt
The documents are then moved to a directory ". \ HISTO \ FINAL".
I have to compare the two last document created and to write the difference in a new document result.txt
I show you my code for findind the two last documents
#echo off & cls
SETLOCAL EnableDelayedExpansion
set "Dossier=.\HISTO\Final"
set /a "n=0, limit=2"
for /F "delims=" %%a in ('dir /B /A-D /O-D /T:W "%Dossier%\*.*"') do (
echo "%%a"
2>nul set /a "n+=1, 1/(limit-n)"||goto :break
)
:break
pause
exit
And le code who compare the two document
Here, I write the name of them but i would like to find the way to write automaticly the result of my first code
findstr /v /g:articles_Final_2016_01_04.txt articles_Final_2016_02_04.txt >result.txt
#echo off
cls
SETLOCAL EnableDelayedExpansion
set "Dossier=.\HISTO\Final"
set /a "n=0, limit=2"
for /F "delims=" %%a in ('dir /B /A-D /O-D /T:W "%Dossier%\*.*"') do (
echo "%%a"
set "file[!n!]=%%a"
2>nul set /a "n+=1, 1/(limit-n)"||goto :break
)
:break
set file
echo findstr /v /g:%Dossier%\%file[0]% %Dossier%\%file[1]%
pause
exit
(untried)
The findstr command will just be echoed - you'd need to check it and redirect the output.
the set file command is simply a way of displaying all variables that start with file.
Here, the final solution
#echo off
cls
SETLOCAL EnableDelayedExpansion
set "Dossier=.\HISTO\FINAL"
set /a "n=0, limit=2"
for /F "delims=" %%a in ('dir /B /A-D /O-D /T:W "%Dossier%\*.*"') do (
echo "%%a"
set "file[!n!]=%%a"
2>nul set /a "n+=1, 1/(limit-n)"||goto :break
)
:break
set file
findstr /v /g:%Dossier%\%file[0]% %Dossier%\%file[1]% >>difference.txt
::fc /L %Dossier%\%file[0]% %Dossier%\%file[1]% >>difference.txt
pause
exit
I have the below code which someone gave to me but I don't know how to put it together in a bat file so it runs successfully.
The aim is to find the latest (last modified) file in c:/ and compare it with c:/2.txt and output the differences into c:/786.txt
cd /d c:\
for /f %%a in ('dir /b /o-d /a-d /tw') do (set latest=%%a & goto :eof)
for /f "tokens=1*" %%a in (
'diff c:\%latest% c:\2.txt ^| findstr /r /c:"^<" /c:"^>"'
) do #echo %%b >>c:\786.txt
Can someone please put this code together for me.
cd /d c:\
set "latest="
for /f %%a in ('dir /b /o-d /a-d /tw') do (set "latest=%%a" & goto :found)
:found
if not defined latest exit /b
for /f "tokens=1,*" %%a in (
'diff "c:\%latest%" "c:\2.txt" ^| findstr /r /c:"^<" /c:"^>"'
) do (
>> "c:\786.txt" echo(%%b
)
Ordering by date descending, the latest file is the first, so on first iteration assign the file name and exit of the for loop.
Then check if any file has been found. It not, end of the script
If we have a file, compare latest file against the indicated one and send the filtered lines to the final file.
EDIT - Refactor code to made it more usable and adapt to comments. Search for last file in folder moved to a subroutine.
#echo off
setlocal enableextensions disabledelayedexpansion
call :getLatestFileInFolder "c:\" latestC
call :getLatestFileInFolder "d:\" latestD
if not defined latestC ( echo NO File in C & exit /b )
if not defined latestD ( echo NO File in D & exit /b )
for /f "tokens=1,*" %%a in (
'diff "%latestC%" "%latestD%" ^| findstr /r /c:"^<" /c:"^>"'
) do (
>> "c:\786.txt" echo(%%b
)
endlocal
exit /b
:getLatestFileInFolder folderToSearch variableToReturn
setlocal
set "folder=%~1" & if not defined folder set "folder=%cd%"
set "latest="
pushd "%folder%"
for /f "tokens=*" %%a in ('dir /b /o-d /a-d /tw 2^>nul') do (set "latest=%%~fa" & goto :latestFileFound)
:latestFileFound
popd
endlocal & set "%~2=%latest%" & goto :eof
I have a directory of files for example:
\1.gif
\1.pdf
\1.doc
\2.gif
\2.pdf
\2.doc
\3.gif
\4.gif
How do I get a file with just the list of files (with extensions) that have unique filenames? (i.e. 3.gif, 4.gif)
Thanks
This does not work with special characters like !, = and more.
#ECHO OFF &SETLOCAL
for %%a in (*) do set ".%%~na=%%~xa"& set /a $%%~na+=1
for /f "tokens=1*delims==." %%a in ('set .') do for /f "tokens=2delims==" %%c in ('set "$%%a"') do if %%c==1 echo(%%a.%%b
i havent tested it, but try this:
#echo off
setlocal enabledelayedexpansion
pushd path\to\dir
for /f %%i in ('dir /b *.gif') do (
find "%%~ni" "%tmp%\u" >nul 2>&1 || echo %%~ni >> "%tmp%\u"
)
for /f %%i in ('type "%tmp%\u"') do (
set inc=
for /f %%j in ('dir %%i.gif /b') do set /a inc+=1
if !inc! EQU 1 (dir /b %%i.* ^|find "log" /v >> log)
)
please feel free to comment if there are any mistakes, not in a position to test it right now.
This will work as long as none of the file names contain the = character:
#echo off
setlocal
for /f "eol== delims==" %%V in ('"set _ 2>nul"') do set "%%V="
for %%F in (*) do if not defined _%%~nF (set "_%%~nF=%%F") else set "_%%~nF=="
for /f "eol== tokens=2 delims==" %%F in ('"set _|findstr /v =="') do #echo %%F
EDIT
If you want to restrict output to only one file type, .gif for example, then all you need is an extra FINDSTR:
#echo off
setlocal
for /f "eol== delims==" %%V in ('"set _ 2>nul"') do set "%%V="
for %%F in (*) do if not defined _%%~nF (set "_%%~nF=%%F") else set "_%%~nF=="
for /f "eol== tokens=2 delims==" %%F in ('"set _|findstr /v ==|findstr /lie .gif"') do #echo %%F
I have a folder where files are dumped with timestamps...
filename_ver20130405121320.csv
I wish to create a batch script that makes sure 5 files have been created with todays date.
im guessing i will need to use a for loop with a date limit of today.
FOR /r %foldername% %%g IN (*.csv) DO (
echo %%~nxg
)
using a forfiles statement lists the files, is it possible to use a counter and +=1 every time it displays a filename?
forfiles /S /P %foldername% /m *.csv /d 0
the logic is
if number of files in a foldername is less than 5 where file created is today
echo error! missing files
any help would be much appreciated
date returned on machine as Mon 22/07/2013
use this to set date
:: set date
FOR /F "TOKENS=1* DELIMS= " %%A IN ('DATE/T') DO SET CDATE=%%B
FOR /F "TOKENS=1,2 eol=/ DELIMS=/ " %%A IN ('DATE/T') DO SET dd=%%B
FOR /F "TOKENS=1,2 DELIMS=/ eol=/" %%A IN ('echo %CDATE%') DO SET mm=%%B
FOR /F "TOKENS=2,3 DELIMS=/ " %%A IN ('echo %CDATE%') DO SET yyyy=%%B
SET setDate=%dd%/%mm%/%yyyy%
#ECHO OFF
SETLOCAL enabledelayedexpansion
SET yyyy=2013
SET mm=07
SET dd=22
SET count=0
FOR /f %%g IN ('dir /b /a-d *%yyyy%%mm%%dd%????.csv') DO (
SET filename=%%~ng
SET filename=!filename:~-12,-4!
if "!filename!"=="%yyyy%%mm%%dd%" SET /a count+=1
)
ECHO %count%
GOTO :EOF
I've simply set yyyy,mm,dd to constants, obviously - just poke your date-decoder in as appropriate.
Note that you could prefix the filemask with a directoryname if required - and enclose the entire filemask in "rabbit's ears" if there are spaces or other confounding characters in the resultant mask.
Important: the filemask is merely a primary filter. The dir would list a file named filename_ver2013040512132.csv for instance (1 digit missing...) so the gymnastics with the processing would still be required.
I'm also assuming relatively sane filenames. Likely ! in a filename would cause conniptions.
I came up with this and it seems to work so far
for /f "tokens=2" %%I in ("%date%") do set today=%%I
for /f "tokens=5" %%G in ('dir %foldername% /a-d ^| find "%today%"') do (
set /a fileCounter += 1
echo %%G
)
echo %fileCounter%
This may work (untested): edited to check only the date in yyyymmdd format
#echo off
for /f "delims=" %%a in ('wmic OS Get localdatetime ^| find "."') do set dt=%%a
set datestamp=%dt:~0,8%
for /f %%a in ('dir "*ver%datestamp%*.csv" /b /a-d^|find /c /v "" ') do (
if %%a LSS 5 echo files are missing
)