Suppose my directory contains these files
dir C:\data\
Statistics_A-1-1_2012-10-21 00_10_19.csv
Statistics_B-1-1_2012-10-21 00_12_01.csv
How do I write a script in batch that gets today's date and grabs all the files with that date in it. If the files are missing tag A-1-1 or tag B-1-1, it should print an error for the missing file for that tag. Ideally, I would like to provide a date range as argument to the script. If not provided, it defaults to today's date
I am used to bash and new to windows programming. I also don't have any scripting languages such as perl, python, etc available. Any help appreciated. Cheers.
#echo off
for /F "tokens=1-3 delims=/" %%a in ("%date%") do set today=%%c-%%a-%%b
for %%a in (*%today%*.csv) do (
for /F "tokens=2 delims=_ " %%b in ("%%a") do (
if %%b equ %today% (
echo %%a ERROR: Missing tab
) else (
echo %%a
)
)
)
You may process a range of dates using Julian Day Numbers this way:
set startJDN=Julian Day Number of start of range
set endJDN=Julian Day Number of end of range
for %%a in (*%today%*.csv) do (
set fileJDN=Julian Day Number of file %%a
if !fileJDN! geq %startJDN% if !fileJDN! leq %endJDN% (
echo The file is in range, process it...
)
)
See this post: Bat file for moving files
The easiest way to get the date parts is with WMIC.(As you did't mentioned what you want to do with files here are only listed):
EDITED VERSION:
#echo off
FOR /F "skip=1 eol=D tokens=1,2,3 delims= " %%A IN ('WMIC Path Win32_LocalTime Get Year^,Month^,Day /Format:table') DO (
SET TODAY=%%A-%%B-%%C
setlocal ENABLEDELAYEDEXPANSION
if [!TODAY!] NEQ [--] (
goto :(endOfLoop^)
)
endlocal
)
:(endOfLoop^)
echo %TODAY%
DIR /B "Statistics_A-1-1_%TODAY% *.csv"
DIR /B "Statistics_B-1-1_%TODAY% *.csv"
Related
Couldn't find an answer that wasn't very specific to someone else's problem.
I'd like to place a bat file in a directory and run it to achieve the following:
Replace all initial '-' (hyphen) with ' - ' (space-hyphen-space)
Replace any 3 char Month names (Jan,Feb,...Dec) with two-digit month number preceeded and followed by a hyphen ('Jan' = '-01-' , 'Mar' = '-03-')
So the following:
32432492-2015Jan23-2015Feb23.pdf
32432492-2015Feb24-2015Mar24.pdf
32432492-2015Mar25-2015Apr29.pdf
becomes:
32432492 - 2015-01-23 - 2015-02-23.pdf
32432492 - 2015-02-24 - 2015-03-24.pdf
32432492 - 2015-03-25 - 2015-04-29.pdf
I'd like the "rename" to only run once (instead of renaming all files over and over). It should do this for all files in current directory (except the current bat file of course).
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir\t w o"
FOR /f "delims=" %%a IN (
'dir /b /a-d "%sourcedir%\*-*" '
) DO (
SET "newname=%%a"
FOR %%b IN ("Jan=-01-" "Feb=-02-" "Mar=-03-" ) DO SET "newname=!newname:%%~b!"
FOR /f "tokens=1*delims=-" %%b IN ("!newname!") DO SET "newname=%%b - %%c"
IF /i NOT "!newname!"=="%%a" ECHO(REN "%sourcedir%\%%a" "!newname!"
)
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
I expect that you would have the sense to complete the month/number set in the form given.
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.
Revision
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir\t w o"
FOR /f "delims=" %%a IN (
'dir /b /a-d "%sourcedir%\*-*" '
) DO (
SET "newname=%%a"
FOR %%b IN ("Jan=/01/" "Feb=/02/" "Mar=/03/" ) DO SET "newname=!newname:%%~b!"
FOR /f "tokens=1,2*delims=-" %%b IN ("!newname!") DO SET "newname=%%b - %%c - %%c"
IF /i NOT "!newname!"=="%%a" ECHO REN "%sourcedir%\%%a" "!newname:/=-!"
)
GOTO :EOF
You said "Replace all initial '-' (hyphen) with ' - ' (space-hyphen-space)" which I took to mean "the initial hyphen in the name".
I am running this bat script, fileNames.bat > print.txt, to get all file Names.
#echo off
setlocal disableDelayedExpansion
:: Load the file path "array"
for /f "tokens=1* delims=:" %%A in ('dir /s /b^|findstr /n "^"') do (
set "file.%%A=%%B"
set "file.count=%%A"
)
:: Access the values
setlocal enableDelayedExpansion
for /l %%N in (1 1 %file.count%) do echo !file.%%N!
However, I would also like to get in the output the creation and modification date for each file path.
My current output looks like that:
C:\Programs\FirefoxPortable\fileNames.bat
C:\Programs\FirefoxPortable\Firefox
C:\Programs\FirefoxPortable\print.txt
C:\Programs\FirefoxPortable\Firefox\App
C:\Programs\FirefoxPortable\Firefox\Data
Any suggestions, how to get the creation and modification date next to each file path?
I appreciate your replies!
Following .bat script produces a csv-like output with | vertical line delimited values of next pattern:
type|creation datetime|modification datetime|full path|
Delayed expansion kept disabled as there are file names containig ! exclamation mark(s): see the call set trick in Variables: extract part of a variable (substring) and in CALLing internal commands.
Note that retrieving creation date and time discriminates between folders and files.
%%G tokenization could vary for another regional settings!
#ECHO OFF
#SETLOCAL enableextensions disableDelayedExpansion
:: Set the working directory and store the previous folder/path
pushd d:\test
:: Load the file path "array"
set "file.count=0"
for /f "tokens=1* delims=:" %%A in ('dir /s /b^|findstr /n "^"') do (
set "file.%%A=%%B"
set "file.count=%%A"
)
:: Restore path/folder most recently stored by the PUSHD command
popd
:: Access the values (keep )
set /A "ii=0"
:loop
if %ii% GEQ %file.count% goto :loopend
set /A "ii+=1"
call set "file.curr=%%file.%ii%%%"
if exist "%file.curr%\" (
rem folder
for %%g in ("%file.curr%") do (
set "defined="
for /F "skip=5 tokens=1,2" %%G in ('
dir /-c /a:d /t:C "%file.curr%"
') do (
if not defined defined (
echo FLDR^|%%G %%H^|%%~tg^|%file.curr%^|
set "defined=%%~tg %%G %%H"
)
)
)
) else (
rem file
for %%g in ("%file.curr%") do (
set "defined="
for /F "skip=5 tokens=1,2" %%G in ('
dir /-c /a:-d /t:C "%file.curr%"
') do (
if not defined defined (
echo FILE^|%%G %%H^|%%~tg^|%file.curr%^|
set "defined=%%~tg %%G %%H"
)
)
)
)
goto :loop
:loopend
ENDLOCAL
goto :eof
My current output looks as follows (reduced to reasonable size):
==>D:\bat\SO\31824138.bat
FILE|26.07.2015 11:02|26.07.2015 11:02|d:\test\File N.txt|
FLDR|24.07.2015 20:21|05.08.2015 18:44|d:\test\set|
FILE|24.07.2015 20:23|24.07.2015 20:23|d:\test\set\hklm.txt|
FILE|24.07.2015 20:26|24.07.2015 20:30|d:\test\set\regs.txt|
FILE|05.08.2015 18:44|05.08.2015 18:45|d:\test\set\t!exclam!t.txt|
==>
I am currently using the following command to get the last modification time of files with a given pattern.
for /r C:\ %F in ("*.txt") do #echo "%~nxF", "%~tF"
How do I get the creation date instead?
#echo off
for /f "skip=5 tokens=1,2,4,5* delims= " %%a in ('dir /a:-d /o:d /t:c') do (
if "%%~c" NEQ "bytes" (
echo(
#echo file name: %%~d
#echo creation date: %%~a
#echo creation time: %%~b
echo(
)
)
But it depends on time settings.Another way is to use WMIC or embedded in bat jscript or vbscript or powershell.
EDIT (with WMIC - not avaialable in home editions of windows , but does not depend on time settings):
#echo off
set "target_dir=C:\some_dir"
for /f "tokens=2 delims=:" %%d in ("%target_dir%") do (
set "data_path=%%d"
)
set data_path=%data_path:\=\\%\\
echo %data_path%
pushd %target_dir%
WMIC DATAFILE WHERE "PATH='%data_path%'" GET CreationDate,Caption
for /r D:\MyFolder %F in ("PartOfFileName*.ZIP") do SET FileNameCreated=%~tF
echo Minute = %FileNameCreated:~14,2%
echo Hour = %FileNameCreated:~11,2%
echo AM/PM = %FileNameCreated:~17,2%
echo Day = %FileNameCreated:~0,2%
echo Month = %FileNameCreated:~3,2%
echo Year = %FileNameCreated:~6,4%
I am trying to create a windows script that should generate this kind of filename everytime I run it: filename1, filename2, filename3 and so on. Here is what I have so far:
(
#echo off
wmic logicaldisk get size,freespace,caption
) > disk.txt
I hope you can help me. Thanks!!
:: make a tempfile
:maketemp
SET "tempfile=%temp%\%random%"
IF EXIST "%tempfile%*" (GOTO maketemp) ELSE (ECHO.>"%tempfile%a")
You now have any number of filenames available.
%tempfile%a exists and is empty, but %tempfile%anythingelse should be available for use.
#ECHO OFF
SETLOCAL
SET "basename=filename"
SET /a outname=0
:genloop
SET /a outname+=1
IF EXIST "%basename% %outname%.txt" GOTO genloop
SET "outname=%basename% %outname%.txt"
ECHO %outname%
GOTO :EOF
Ah - increment the destination filename on each run. This should do that. It's not actually creating a file - you'd need to create the file %outname% each time to have it increment...
(the space between %basename% and %outname% is optional, of course - omit it if desired.)
edited to include .txt
This will give you up to 1000 filenames but you can go higher, up to 2 Billion, but the higher you go the longer the delay will be before it picks a filename.
#echo off
for /L %%a in (1,1,1000) do if not defined filename if not exist "filename%%a.txt" set "filename=filename%%a.txt"
(
wmic logicaldisk get size,freespace,caption
) > "%filename%"
#echo off
setlocal enableextensions
call :getNextFilename "filename*.txt" nextFilename
echo %nextFilename%
echo test > "%nextFilename%"
call :getNextFilename "%cd%\filename*.txt" nextFilename
echo %nextFilename%
echo test > "%nextFilename%"
endlocal
exit /b
:getNextFilename whatToSearch returnVariable
setlocal enableextensions enabledelayedexpansion
for /f %%a in ("$\%~1"
) do for /f "tokens=1,* delims=*" %%b in ("%%~nxa"
) do ( set "left=%%b" & set "right=%%c" )
set "max=0"
for %%a in ("%~1"
) do for /f "tokens=1 delims=%left%%right% " %%b in ("%%~nxa"
) do for /f "tokens=* delims=0 " %%c in ("0%%~b"
) do if %%~c geq !max! set /a "max=%%c+1"
endlocal & set "%~2=%~dp1%left%%max%%right%" & exit /b
This should find the next file in sequence independently of the existence of holes in the numeration of the files. A path can be included or omitted. The * will be used as the placeholder for the numeration. BUT this will not work if files or included paths have "problematic" characters.
If the date/time of creation of the file can be considered, then this version can be optimized as
:getNextFilename whatToSearch returnVariable
setlocal enableextensions disabledelayedexpansion
for /f %%a in ("$\%~1"
) do for /f "tokens=1,* delims=*?" %%b in ("%%~nxa"
) do ( set "left=%%b" & set "right=%%c" )
set "max=0"
for /f "delims=" %%a in ('dir /tc /o-d /b "%~1" 2^>nul'
) do for /f "tokens=1 delims=%left%%right% " %%b in ("%%~nxa"
) do for /f "tokens=* delims=0 " %%c in ("0%%~b"
) do set /a "max=%%c+1" & goto done
:done
endlocal & set "%~2=%~dp1%left%%max%%right%" & exit /b
that will take the latest created instance of the file set.
I finally figured out where to put the .txt extension. This is from #Magoo's answer but I wanted the file to be a text file so I placed the .txt twice in order for it to work properly.
#ECHO OFF
SETLOCAL
SET "basename=DISK-OUT"
SET /a outname=0
:genloop
SET /a outname+=1
IF EXIST "%basename% %outname%.txt" GOTO genloop
SET "outname=%basename% %outname%.txt"
(
wmic logicaldisk get size,freespace,caption
) > "%outname%"
GOTO :EOF
I have multiple files in a directory with the formatL: data_yyyy_mm_dd_ss.info.dat
I am trying to write a batch script that will ask for user start/end date input (and assuming the user's input will match the format of the files yyyy_mm_dd) I then want the script to do a merge of all relevant files.
Ex Files: data_2013_12_01_32.info.dat; data_2013_12_02_44.info.dat; data_2013_12_03_22.info.dat; data_2013_12_04_33.info.dat; data_2013_12_05_52.info.dat; data_2013_12_06_12.info.dat
Ex Script:
#echo off
set /p start= Start Date:
set /p end= End Date:
copy /b ????
Ex User Input: 2013_12_02 and 2013_12_05
Ex Output: Merge files 2013_12_02 through 2013_12_05.
Thanks for any help in advance.
I'll assume you know what you are doing, and it is valid to concatenate your binary files.
The following should work, as long as all files that match the FOR filter are candidates for merging, and as long as the user always enters dates in the correct format (yyyy_mm_dd):
#echo off
setlocal
set /p start= Start Date:
set /p end= End Date:
set "out=output.info.dat"
for %%F in (data_????_??_??_??.info.dat) do (
for /f "tokens=1-3 delims=_" %%A in ("%%F") do (
if "%%A_%%B_%%C" geq "%start%" if "%%A_%%B_%%C" leq "%end%" (
copy /b "%out%"+"%%F" "%out%" /b
)
)
)
As an alternative to using COPY, you should be able to redirect the output of FINDSTR and get the same result.
#echo off
setlocal
set /p start= Start Date:
set /p end= End Date:
>output.info.dat (
for %%F in (data_????_??_??_??.info.dat) do (
for /f "tokens=1-3 delims=_" %%A in ("%%F") do (
if "%%A_%%B_%%C" geq "%start%" if "%%A_%%B_%%C" leq "%end%" (
findstr "^" "%%F"
)
)
)
)
I'm not sure which is faster, COPY or FINDSTR
It has no checks on almost anything. Be careful.
Ask for start and end date. Generate min and max files based on data input and iterate over the ordered list of files. If a file is found, it is readed with findstr (first option was type command, but it's 4 to 5 times slower) and all output redirected to final merged file.
#echo off
setlocal enableextensions disabledelayedexpansion
set /p "start=Start date :"
set /p "end=End date :"
set "start=data_%start%_00.info.dat"
set "end=data_%end%_99.info.dat"
>merged.info.dat (
for /f "tokens=*" %%f in ('dir /on /b "data_????_??_??_??.info.dat"') do (
if /i "%%f" geq "%start%" if /i "%%f" leq "%end%" findstr "^" "%%f"
)
)
For a long list of files, search can be abreviated. In this moment i don't know how to skip the initial non matching part of the list of files, but the final part can be easyly skipped
#echo off
setlocal enableextensions disabledelayedexpansion
set /p "start=Start date:"
set /p "end=End date:"
set "start=data_%start%_00.info.dat"
set "end=data_%end%_99.info.dat"
>output.info.dat (
for /f "tokens=*" %%f in ('dir /on /b "data_????_??_??_??.info.dat"') do (
if /i "%%f" geq "%start%" if /i "%%f" leq "%end%" ( findstr "^" "%%f" ) else ( goto :endMerge )
)
)
:endMerge