I'm looking for a way to retrieve the file time-- down to the SECOND-- in a batch file. I'm trying to do an operation on all files that have been modified more recently than another file.
I've used this method:
for %%a in (keyfile.dat) do set LAST_PUBLISHED_DATE=%%~ta
rem for %%x in (%LAST_PUBLISHED_DATE:/= %) do echo %%x
for /f "tokens=1,2 delims= " %%a in ("%LAST_PUBLISHED_DATE%") do (
set DATE=%%a
set TIME=%%b
)
for /f "tokens=1,2,3 delims=/" %%a in ("%DATE%") do (
set MON=000%%a
set DAY=000%%b
set YEAR=%%c
set MON=!MON:~-2,2!
set DAY=!DAY:~-2,2!
set YEAR=!YEAR:~-2,2!
)
for /f "tokens=1,2 delims=:" %%a in ("%TIME%") do (
set HOUR=000%%a
set MIN=000%%b
set HOUR=!HOUR:~-2,2!
set MIN=!MIN:~-2,2!
)
set INT_LASTPUBLISHEDDATE=%YEAR%%MON%%DAY%%HOUR%%MIN%
And I've been using that to turn the last modified date into an int which I can compare against other files. Works great. Except sometimes I might need to run this batch more often than once a minute.
Is there some extended way that I can also get "seconds" from the file modified time? The method above returns it in yyyy/mm/dd hh:mm format.
(Most ideal situation would be to just get the unix time of the last modification... haven't been able to locate any way to do that though!)
Thanks!
you can leverage vbs for this purpose.
#Echo Off & Setlocal EnableDelayedExpansion
(For /F "Delims=" %%G in ('TYPE "%~F0" ^| Findstr /BLIC::::') Do (Set "Line=%%G"&Echo/!Line:~3!))>"filetimes.vbs"
For /F "Delims=" %%G in ('cscript //nologo filetimes.vbs %~nx0')Do Set "%%G"
Set %~F0[
Exit /B
:::Set objFSO = CreateObject("Scripting.FileSystemObject")
:::if WScript.Arguments.Count = 0 Then
::: WScript.Quit
:::End If
:::strfileFolder = objFSO.GetAbsolutePathName(WScript.Arguments(0))
:::'this line only works with cscript
:::Set v = objFSO.GetFile(WScript.Arguments(0))
:::dm=v.DateLastModified
:::dc=v.DateCreated
:::da=v.DateLastAccessed
:::WScript.StdOut.WriteLine(strfileFolder&"[Created]="&dc)
:::WScript.StdOut.WriteLine(strfileFolder&"[Modified]="&dm)
:::WScript.StdOut.WriteLine(strfileFolder&"[Accessed]="&da)
Related
I was able to list mp4 files in a directory with a for loop, and depending on how many files are listed, a parameter is passed to the choice command. What I wasn't able to do is to select a file from a list that has been created with a for loop? This way I hope to use the selected file in another command as a parameter.
Here my code:
#echo off
setlocal enableextensions enabledelayedexpansion
set /a count = 0
echo.
for %%f in (*.mp4) do (
set /a count += 1
echo [!count!] %%f
)
for /l %%a in (1,1,%count%) do (
call set "cOpt=%%cOpt%%%%a"
)
echo.
choice /C %cOpt% /M "Select input video:"
echo %errorlevel% # selected option is shown here but no filename
endlocal
#Echo Off & SetLocal EnableExtensions
:Menu
For /F "Delims==" %%G In ('(Set File[^) 2^> NUL') Do Set "%%G="
For /F "Tokens=1,* Delims=[]" %%G In ('(Set PATHEXT^=^) ^& %__AppDir__%where.exe ".":"*.mp4" 2^> NUL ^| %__AppDir__%find.exe /N /V ""') Do Set "File[%%G]=%%~nxH" & Echo %%G. %%~nxH
If Not Defined File[1] GoTo :EOF
:Select
Set "#="
Set /P "#=Choose a file from the list by entering its item number. "
For /F "Tokens=1,* Delims==" %%G In ('(Set File[%#%]^) 2^> NUL ^| %__AppDir__%find.exe "="') Do Set "File[#]=%%H"
If Not Defined File[#] GoTo Select
:Main
Echo You chose item number %#% which was assigned to "%File[#]%" & Pause
You would obviously modify the last line to be your required command with parameter.
If you wish to include the full paths, simply change both instances of %%~nxH on line 5, to %%H. Additionally if you wish to stipulate a location, instead of the current directory, change ".", on the same line to e.g. "Y:\our\Path".
I am trying to write a windows Batch file to obtain below OUTPUT for given INPUT
INPUT:
//Dev-420/PAVAN/src/main/java/test/abcd/mnop/HealthCheck.java - edit change 1111111
//Dev-420/PAVAN/src/main/java/test/abcd/mnop/HealthStatus.java - edit change 1111111
//Dev-420/PAVAN/src/main/java/test/xyz/Relations.java - edit change 1111111
OUTPUT:
target/classes/test/abcd/mnop/, target/classes/test/abcd/mnop/, target/classes/test/xyz
Below is the script I used, however replacing filename is not working.
#echo off
set "File2Read=files_list.tmp"
SET "BINARY_PATH="
set "FILENAME="
setlocal EnableDelayedExpansion
set "BINARY_FILENAME="
set "lastPart="
set "replaceBinaryPath=target/classes/"
SET "replaceBinaryFileName=,"
set "basePath=//ATT/Dev-420/PAVAN/src/main/java/"
for /f "delims=" %%a in ('Type "%File2Read%"') do (
set "line=%%a"
for /f "tokens=1,2,3,4,5 delims= " %%a in ("!line!") do set FILENAME=%%a
set "BINARY_FILENAME=!FILENAME:%basePath%=%replaceBinaryPath%!"
if not !FILENAME!==!BINARY_FILENAME! (
for %%a in ("!BINARY_FILENAME!/.") do set "lastPart=%%~nxa"
set "BINARY_PATH=!BINARY_FILENAME:!lastPart!=%replaceBinaryFileName%!"
echo !BINARY_PATH!
)
)
endLocal
here, everything works as expected, except below statement,
set "BINARY_PATH=!BINARY_FILENAME:!lastPart!=%replaceBinaryFileName%!"
Since ‘lastPart’ will be the dynamically changing-value, in order to replace it with ‘comma’ It was supposed to work with !lastPart! but its not working and output is word ‘lastPart’
We cant use %lastPart% as it is dynamic variable.
Please help me with replacing a dynamic string with 'comma'.
Please help me out here!
You could use the %%~nxa expression directly, I only changed the parameter name to %%C
..
for /f "delims=" %%a in ('Type "%File2Read%"') do (
set "line=%%a"
for /f "tokens=1,2,3,4,5 delims= " %%a in ("!line!") do set FILENAME=%%a
set "BINARY_FILENAME=!FILENAME:%basePath%=%replaceBinaryPath%!"
if not !FILENAME!==!BINARY_FILENAME! (
for %%C in ("!BINARY_FILENAME!/.") do (
set "BINARY_PATH=!BINARY_FILENAME:%%~nxC=%replaceBinaryFileName%!"
echo !BINARY_PATH!
)
)
)
As #jeb's version didn't work for me, here an alternative
as the usage of %%~dpa changes the the non windows path separator / to \ it is corrected.
:: Q:\Test\2018\09\24\SO_52482593.cmd
#echo off & setlocal EnableDelayedExpansion
set "File2Read=files_list.tmp"
set "BINARY_PATH="
set "replaceBinaryPath=target/classes/"
set "replaceBinaryFileName=, "
set "Output="
for /f %%a in ('Type "%File2Read%"') do (
for /f "tokens=5* delims=\/" %%b in ("%%~dpa") do (
Set "Output=!Output!%replaceBinaryFileName%%replaceBinaryPath%%%c"
)
)
Set "Output=%Output:\=/%"
Echo %Output:~2%
endLocal
Sample output:
> Q:\Test\2018\09\24\SO_52482593.cmd
target/classes/test/abcd/mnop/, target/classes/test/abcd/mnop/, target/classes/test/xyz/
I have this batch file to split a txt file:
#echo off
for /f "tokens=1*delims=:" %%a in ('findstr /n "^" "PASSWORD.txt"') do for /f "delims=~" %%c in ("%%~b") do >"text%%a.txt" echo(%%c
pause
It works but it splits it line by line. How do i make it split it every 5000 lines. Thanks in advance.
Edit:
I have just tried this:
#echo off
setlocal ENABLEDELAYEDEXPANSION
REM Edit this value to change the name of the file that needs splitting. Include the extension.
SET BFN=passwordAll.txt
REM Edit this value to change the number of lines per file.
SET LPF=50000
REM Edit this value to change the name of each short file. It will be followed by a number indicating where it is in the list.
SET SFN=SplitFile
REM Do not change beyond this line.
SET SFX=%BFN:~-3%
SET /A LineNum=0
SET /A FileNum=1
For /F "delims==" %%l in (%BFN%) Do (
SET /A LineNum+=1
echo %%l >> %SFN%!FileNum!.%SFX%
if !LineNum! EQU !LPF! (
SET /A LineNum=0
SET /A FileNum+=1
)
)
endlocal
Pause
exit
But i get an error saying: Not enough storage is available to process this command
This will give you the a basic skeleton. Adapt as needed
#echo off
setlocal enableextensions disabledelayedexpansion
set "nLines=5000"
set "line=0"
for /f "usebackq delims=" %%a in ("passwords.txt") do (
set /a "file=line/%nLines%", "line+=1"
setlocal enabledelayedexpansion
for %%b in (!file!) do (
endlocal
>>"passwords_%%b.txt" echo(%%a
)
)
endlocal
EDITED
As the comments indicated, a 4.3GB file is hard to manage. for /f needs to load the full file into memory, and the buffer needed is twice this size as the file is converted to unicode in memory.
This is a fully ad hoc solution. I've not tested it over a file that high, but at least in theory it should work (unless 5000 lines needs a lot of memory, it depends of the line length)
AND, with such a file it will be SLOW
#echo off
setlocal enableextensions disabledelayedexpansion
set "line=0"
set "tempFile=%temp%\passwords.tmp"
findstr /n "^" passwords.txt > "%tempFile%"
for /f %%a in ('type passwords.txt ^| find /c /v "" ') do set /a "nFiles=%%a/5000"
for /l %%a in (0 1 %nFiles%) do (
set /a "e1=%%a*5", "e2=e1+1", "e3=e2+1", "e4=e3+1", "e5=e4+1"
setlocal enabledelayedexpansion
if %%a equ 0 (
set "e=/c:"[1-9]:" /c:"[1-9][0-9]:" /c:"[1-9][0-9][0-9]:" /c:"!e2![0-9][0-9][0-9]:" /c:"!e3![0-9][0-9][0-9]:" /c:"!e4![0-9][0-9][0-9]:" /c:"!e5![0-9][0-9][0-9]:" "
) else (
set "e=/c:"!e1![0-9][0-9][0-9]:" /c:"!e2![0-9][0-9][0-9]:" /c:"!e3![0-9][0-9][0-9]:" /c:"!e4![0-9][0-9][0-9]:" /c:"!e5![0-9][0-9][0-9]:" "
)
for /f "delims=" %%e in ("!e!") do (
endlocal & (for /f "tokens=1,* delims=:" %%b in ('findstr /r /b %%e "%tempFile%"') do #echo(%%c)>passwords_%%a.txt
)
)
del "%tempFile%" >nul 2>nul
endlocal
EDITED, again: Previous code will not correctly work for lines starting with a colon, as it has been used as a delimiter in the for command to separate line numbers from data.
For an alternative, still pure batch but still SLOW
#echo off
setlocal enableextensions disabledelayedexpansion
set "nLines=5000"
set "line=0"
for /f %%a in ('type passwords.txt^|find /c /v ""') do set "fileLines=%%a"
< "passwords.txt" (for /l %%a in (1 1 %fileLines%) do (
set /p "data="
set /a "file=line/%nLines%", "line+=1"
setlocal enabledelayedexpansion
>>"passwords_!file!.txt" echo(!data!
endlocal
))
endlocal
Test this: the input file is "file.txt" and output files are "splitfile-5000.txt" for example.
This uses a helper batch file called findrepl.bat - download from: https://www.dropbox.com/s/rfdldmcb6vwi9xc/findrepl.bat
Place findrepl.bat in the same folder as the batch file or on the path.
#echo off
:: splits file.txt into 5000 line chunks.
set chunks=5000
set /a s=1-chunks
:loop
set /a s=s+chunks
set /a e=s+chunks-1
echo %s% to %e%
call findrepl /o:%s%:%e% <"file.txt" >"splitfile-%e%.txt"
for %%b in ("splitfile-%e%.txt") do (if %%~zb EQU 0 del "splitfile-%e%.txt" & goto :done)
goto :loop
:done
pause
A limitation is the number of lines in the file and the real largest number is 2^31 - 1 where batch math tops out.
#echo off
setlocal EnableDelayedExpansion
findstr /N "^" PASSWORD.txt > temp.txt
set part=0
call :splitFile < temp.txt
del temp.txt
goto :EOF
:splitFile
set /A part+=1
(for /L %%i in (1,1,5000) do (
set "line="
set /P line=
if defined line echo(!line:*:=!
)) > text%part%.txt
if defined line goto splitFile
exit /B
If the input file has not empty lines, previous method may be modified in order to run faster.
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 want to fetch the current time and create a folder with the name of the time.
How can i fetch the time into a variable?
SET %%DESTINATIONDIRROOT = "I:\directory\"
SET %%DESTINATIONDIRSEPERATOR = "\"
SET %%DESTINATIONDIR = TIME
for /F "usebackq delims=" %%b IN (`DIR /B /S /A "C:\RandomTestFiles\*.*"`) DO #(
XCOPY /Y "%%~b" %%DESTINATIONDIRROOT%%DESTINATIONDIR%%DESTINATIONDIRSEPERATOR
)
Adapt these if you have XP Pro and above. They do not suffer from changes in regional settings and date/time variables, and are padded properly.
:: timestamp YYYYMMDD_HHMMSS
#echo off
for /f "delims=" %%a in ('wmic OS Get localdatetime ^| find "."') do set dt=%%a
set dt=%dt:~0,8%_%dt:~8,6%
echo %dt%
pause
:: timestamp YYYY-MM-DD_HH-MM-SS
#echo off
for /f "delims=" %%a in ('wmic OS Get localdatetime ^| find "."') do set dt=%%a
set dt=%dt:~0,4%-%dt:~4,2%-%dt:~6,2%_%dt:~8,2%-%dt:~10,2%-%dt:~12,2%
echo %dt%
pause
This makes a directory called yyyy-mm-dd_hh-mm:
for /f "tokens=1-4 delims=/ " %%a in ('date /t') do (set bdate=%%c-%%b-%%a)
for /f "tokens=1-2 delims=/:" %%a in ('time /t') do (set btime=%%a-%%b)
md %bdate%_%btime%
For European-style dates (dd-mm-yyyy), use bdate=%%a-%%b-%%c.
For American-style dates (mm-dd-yyyy), use bdate=%%b-%%a-%%c.
NB: A machine locale of en-US would probably reverse the above 2 scenarios.
Consider %DATE% and %TIME%:
SET someVar = %TIME%
Do this: https://stackoverflow.com/a/1254897/431415