BATCH FILE - create folders with every WORKING DAY (no saturday and sunday) - batch-file

I would like to edit the following batch code in order to create a folder with every working day of the year and skip saturday and sunday (i guess it should create 5 consecutive days and skip the next 2)
I would also like the batch file to
skip creating folders for each month(a january folder, a february folder etc) and have all days of the year in the same folder.
add two extra folders in each day folder with 'morning' and 'afternoon'
Ex:
C:\Users\alex\Desktop\2022\1 Jan\Morning
C:\Users\alex\Desktop\2022\1 Jan\Afternoon
all the way to
C:\Users\alex\Desktop\2022\31 Dec\Morning
C:\Users\alex\Desktop\2022\31 Dec\Afternoon
(it would not create 31 dec folder because thats a saturday)
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\years"
SET /p year=### Enter Year [e.g. 2014]:
IF NOT DEFINED year GOTO :EOF
SET year=%year:,=%
IF %year% lss 100 SET /a year=2000+year
IF %year% gtr 1901 IF %year% lss 2099 GOTO generate
ECHO year entered out of range 1901..2099
GOTO :eof
:generate
MD "%sourcedir%"
SET /a feb=year %% 4
IF %feb%==0 (SET "feb=02,February,29") ELSE (SET "feb=02,February,28")
PUSHD "%sourcedir%"
MKDIR %year%
CD %year%
FOR %%a IN ("01,January,31" "%feb%" "03,March,31" "04,April,30" "05,May,31" "06,June,30" "07,July,31" "08,August,31" "09,September,30" "10,October,31" "11,November,30" "12,December,31") DO (
FOR /f "tokens=1-3delims=," %%b IN (%%a) DO (
SET "month=%%c"
SET "month=!month:~0,3!"
MKDIR %%b_%%c
pushd %%b_%%c
FOR /l %%q IN (1,1,%%d) DO MD %%q-!month!-%year%
popd
)
)
popd
GOTO :EOF

This is a very simple task when you use the right method and formulae:
#echo off
setlocal EnableDelayedExpansion
set "i=0"
for %%a in (Mon Tue Wed Thu Fri Sat Sun) do (
set "DayOfWeek[!i!]=%%a"
set /A i+=1
)
set /P "Year=Enter year: "
set /A "leap=28+^!(Year%%4)*^!^!(Year%%400)"
set "MonthNameDays=Jan:31 Feb:%leap% Mar:31 Apr:30 May:31 Jun:30 Jul:31 Aug:31 Sep:30 Oct:31 Nov:30 Dec:31"
rem Get Julian Day Number of Jan/01 of given year
rem adjusted as multiple of day of week: JDN % 7 = 0..6 for Mon..Sun
rem Reference: http://www.hermetic.ch/cal_stud/jdn.htm#comp
set /A "JDN=(1461*(Year+4799))/4+4037/12-(3*((Year+4899)/100))/4-1, MM=100"
for %%a in (%MonthNameDays%) do for /F "tokens=1,2 delims=:" %%x in ("%%a") do (
set /A MM+=1
ECHO md "!MM:~1! %%x"
ECHO pushd "!MM:~1! %%x"
for /L %%d in (1,1,%%y) do (
set /A "JDN+=1, DOW=JDN%%7, DD=100+%%d"
if !DOW! lss 5 (
for %%w in (!DOW!) do (
ECHO md "!DD:~-2! !DayOfWeek[%%w]!"
)
)
)
ECHO popd
)
I focused on the core point of generate folders for Mon..Fri days of week, so I not included some minor details, like generate Morning/Afternoon folders. Also, I just echoed the "MD" commands...

As per my earlier comment, the following batch file gets the assistance of PowerShell:
#Echo Off
SetLocal EnableExtensions
:AskYear
ClS
Set "YYYY="
Set /P "YYYY=Please enter a four digit year from 1900 to 2099 incl.>"
Set YYYY 2>NUL|%SystemRoot%\System32\findstr.exe /R^
"^YYYY=19[0123456789][0123456789]$ ^YYYY=20[0123456789][0123456789]$" 1>NUL || GoTo AskYear
%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile^
"$beginningOfYear = Get-Date -Year %YYYY% -Month 1 -Day 1 -Hour 0 -Minute 0 -Second 0;"^
"$endOfYear = ($beginningOfYear).AddYears(1).AddSeconds(-1);"^
"While ($beginningOfYear -LE $endOfYear) {"^
" $beginningOfYear = ($beginningOfYear).AddDays(1);"^
" If ($beginningOfYear.DayOfWeek -GT 0) {"^
" If ($beginningOfYear.DayOfWeek -LT 6) {"^
" $children=#('Morning','Afternoon');"^
" ForEach ($i In $children) {"^
" md \"$($beginningOfYear.ToString('yyyy\\d MMM'))\$i\"}}}}"
The above example assumes that your culture/locale settings use the first day of the week 0 as the last day of the weekend, and the 6 as the first day of the weekend. If your culture/locale settings use 6 and 5 for those two days respectively, then you'd simply change the code accordingly:
#Echo Off
SetLocal EnableExtensions
:AskYear
ClS
Set "YYYY="
Set /P "YYYY=Please enter a four digit year from 1900 to 2099 incl.>"
Set YYYY 2>NUL|%SystemRoot%\System32\findstr.exe /R^
"^YYYY=19[0123456789][0123456789]$ ^YYYY=20[0123456789][0123456789]$" 1>NUL || GoTo AskYear
%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile^
"$beginningOfYear = Get-Date -Year %YYYY% -Month 1 -Day 1 -Hour 0 -Minute 0 -Second 0;"^
"$endOfYear = ($beginningOfYear).AddYears(1).AddSeconds(-1);"^
"While ($beginningOfYear -LE $endOfYear) {"^
" $beginningOfYear = ($beginningOfYear).AddDays(1);"^
" If ($beginningOfYear.DayOfWeek -LT 5) {"^
" $children=#('Morning','Afternoon');"^
" ForEach ($i In $children) {"^
" md \"$($beginningOfYear.ToString('yyyy\\d MMM'))\$i\"}}}"

Not pure batch, but you can use powershell to help a bit.
#echo off
set "sourcedir=U:\years"
set /p year=### Enter Year [e.g. 2014]:
echo 0..365 ^| %% { $date = Get-Date "%year%-01-01";$date = $date.AddDays($_).ToString("dddd dd MMMM yyyy");Write-Host $date"" }>tmp.ps1
for /F "tokens=1-4*" %%a in ('powershell .\tmp.ps1') do (
if "%%~d" == "2022" if not "%%a" == "Saturday" if not "%%a" == "Sunday" (
echo mkdir "%sourcedir%\%%c %%d\%%a %%b\Morning"
echo mkdir "%sourcedir%\%%c %%d\%%a %%b\Afternoon"
)
)
del /Q tmp.ps1
PS!! you don't have to use the temp file at all, I just don't have the time now to do all the escaping of special characters, but it will help you in the right direction, if you can use hybrids.
You can move the year/month/days around as you please. If you want short Month and Day (Dec, Mon instead of December Monday) change the format in the powershell portion:
echo 0..365 ^| %% { $date = Get-Date "%year%-01-01";$date = $date.AddDays($_).ToString("ddd dd MMM yyyy");Write-Host $date"" }>tmp.ps1
Result:

Related

Using batch file, how to name a file like year_month with date increased in 1 month from now?

I would like to name a file with the following format:
2019-11
2019-12
2020-01
Basically, name a file with the date increased in 1 month from now using batch file
Since I already have this code, I'll just put it here in case you can modify it for your needs. It is language (English) dependent as written.
:: get year, month, day for today
for /f "skip=1 tokens=2-4 delims=(-)" %%a in ('"echo.|date"') do (
for /f "tokens=1-3 delims=/.- " %%A in ("%Date:* =%") do (
set %%a=%%A&set %%b=%%B&set %%c=%%C)
)
)
set /a "yy=10000%yy% %% 10000 %% 2000 + 2000,mm=100%mm% %% 100,dd=100%dd% %% 100"
:: yy is the 4 digit year presumed to be between year 2000 and year 2999; mm is the month; and dd is the day
:: Add 1 month
if /i %mm%==12 (
set mm=0
set /a yy+=1
)
set /a mm+=1
:: mm2 is zero-padded month
:: Pad
set mm2=0%mm%
set mm2=%mm2:~-2%
According to my advice to use a more suitable scripting language, and based aroung the fact you did not respond to my additional question via comment, here is a powershell suggestion:
Get-ChildItem -Path "." -Filter "????-??" |
Where-Object {!$_.PSIsContainer -And $_.Name -Match "^[\d]{4}-[\d]{2}$"} |
Rename-Item -NewName {$(([DateTime]$_.Name).AddMonths(1)).ToString('yyyy-MM')}
If you really do have extensions, then you'll need to adjust the -Filter string pattern and incorporate .BaseName, and both .BaseName and .Extension instead of using .Name.
For bat using independent date/time layout with wmic
#echo off && Setlocal EnableDelayedExpansion
for /f ^tokens^=1^delims^=. %%i in ('"wmic OS Get localdatetime|findstr [0-9]"')do set "_dt=%%i"
if "!_dt:~4,2!" == "12" (set "_m=101" && set /a "_y=!_dt:~0,4!+1") else (set /a "_m=!_dt:~4,2!+101"
set "_y=!_dt:~0,4!") && set "_dn=!_y!-!_m:~1!") && for /f "delims=" %%F in ('dir /s /b "*_"')do (
rename "%%~dpnF" "!_dn!")
:: Result for today 2019-11-14 ::
rename "2019_11" "2019-12"

Select info from txt in bat file

There is a text file that stores a log of processed files in the following format:
Name: kn-25.txt Date: 01.02.2013 Time: 14:50
The task is to write a batch file which will make a selection from this file for a given month (mm) and year (yyyy) into the file result.txt.
#echo off
chcp 1251 >nul
setlocal EnableDelayedExpansion
echo Введіть початковий файл:
set /p in_file=%~nx1
if not exist %in_file% goto end
del D:\result.txt
set /a count=0
set /a con=0
set /a min=101
set /p month=Введіть місяць:
if [%month%] == [] goto end
set /p year=Введіть рік:
if [%year%] == [] goto end
goto start
:start
if count equ 0 (
set /a con=0
) else (
set /a con=0-!count!
)
for /f "tokens=*" %%i in (%in_file%) do (
for /f "tokens=1-6" %%a in ("%%~i") do (
for /f "delims=. tokens=1-3" %%u in ("%%~d") do (
if "%%v"=="%month%" if "%%w"=="%year%" (
set /a con=!con!+1
if "%%u" leq "!min:~-2!" (
set /a min1=!min!-1
if "%%u" neq "!min1:~-2!" (
set /a count=!count!+1
echo !count!. %%i>>D:\result.txt
)
)
)
)
)
)
if %con% neq %count% (
set /a min=!min!+1
goto start
) else (
type D:\result.txt
echo
#pause
endlocal
exit /B
)
:end
echo Ви не ввели параметр!
echo
#pause
endlocal
exit /B
I wrote this code, but got an error:
Cannot find the file Name:.
Any suggestions?
Note: information in the generated file must be sorted by date
Example:
Initial file content:
Name: kn-25.txt Date: 07.03.2013 Time: 14:50
Name: kn-26.txt Date: 02.03.2013 Time: 23:50
Name: MyFil.txt Date: 03.08.2012 Time: 12:00
Name: ca-21.txt Date: 28.03.2013 Time: 01:00
Name: ca-25.txt Date: 01.30.2012 Time: 10:05
Input: 03.2013
Output:
Name: kn-26.txt Date: 02.03.2013 Time: 23:50
Name: kn-25.txt Date: 07.03.2013 Time: 14:50
Name: ca-21.txt Date: 28.03.2013 Time: 01:00
a slightly different approach (slower than the other ones, but working as intended):
#echo off
setlocal EnableDelayedExpansion
set in_file=t.txt
set month=03
set year=2013
(for /l %%a in (100,1,131) do (
set "day=%%a"
findstr "!day:~-2!.%month%.%year%" %in_file%
))>result.txt
For sorting we ignore the first 22 characters sort command.
#echo off
chcp 1251 >nul
setlocal EnableDelayedExpansion
echo Введіть перший параметр:
set /p in_file=%~f1
if not exist %in_file% goto end
set /p month=Введіть місяць:
if [%month%] == [] goto end
set /p year=Введіть рік:
if [%year%] == [] goto end
findstr /C:"%month%.%year%" %in_file% | sort /+22 > D:\result.txt
type D:\result.txt
pause
exit /B
:end
echo Ви не ввели параметр!
pause
exit /B
We can use findstr /O if we want an offset on each line.
If you are on a supported Windows machine, it will have PowerShell on it. Here is one way to do it. This assumes that the date is in DD.MM.YYYY format.
Since it has already parsed out the date and time with a regex, it creates a [DateTime] to associate with the log file line. It then uses this [DateTime] to sort the file, but only outputs the log file line.
[CmdletBinding()]
param (
[Parameter(Mandatory=$true,Position=0)]
[string]$LogFile
,[Parameter(Mandatory=$true,Position=1)]
[int]$Year
,[Parameter(Mandatory=$true,Position=2)]
[int]$Month
)
Get-Content -Path $LogFile |
ForEach-Object {
if ($_ -match 'Name: .* Date: ((\d*).(\d*).(\d*)) Time: ((\d*):(\d*))') {
#$Matches
$fday = [int]$Matches[2]
$fmonth = [int]$Matches[3]
$fyear = [int]$Matches[4]
$fhour = [int]$Matches[6]
$fminutes = [int]$Matches[7]
if (($fmonth -eq $Month) -and ($fyear -eq $Year)) {
[PSCustomObject]#{
Line = $_
Timestamp = Get-Date -Year $fyear -Month $fmonth -Day $fday `
-Hour $fhour -Minute $fminutes -Second 0
}
}
}
} |
Sort-Object -Property Timestamp |
ForEach-Object { $_.Line }
Invoke it using the following command. If you do not provide the parameters, PowerShell will prompt for them. That is like using SET /P in a cmd.exe bat file script.
.\logparse.ps1 -LogFile '.\logparse.in.txt' -Year 2013 -Month 2
If you must run it from a cmd.exe shell, use:
powershell -NoLogo -NoProfile -File ".\logparse.ps1"
The following code uses a temporary file containing the lines from the input file filtered by the given date information (month and year), but with each line prefixed by year, month and day as well as the time value, which allows easy alphabetic sorting that is fine for your fixed-width date/time formats:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "IN_FILE=%~1"
set "OUT_FILE=D:\result.txt"
set "TMP_FILE=%TEMP%\%~n0_%RANDOM%.tmp"
set "MONTH=03"
set "YEAR=2013"
rem /* Filter lines for given month and year, then write them
rem to temporary file, preceded by year, month, date and `:`: */
> "%TMP_FILE%" (
for /F usebackq^ delims^=^ eol^= %%L in ("%IN_FILE%") do (
for /F "tokens=3-5 delims=:" %%D in ("%%L") do (
for /F "tokens=1-3 delims=. " %%A in ("%%D") do (
if "%%B" == "%MONTH%" if "%%C" == "%YEAR%" (
echo(%%C%%B%%A%%E%%F:%%L
)
)
)
)
)
rem /* Sort content of temporary file, remove prefix
rem up to the (first) `:` and write to result file: */
> "%OUT_FILE%" (
for /F "tokens=1* delims=:" %%E in ('sort "%TMP_FILE%"') do (
echo(%%F
)
)
rem // Clean up temporary file:
del "%TMP_FILE%"
endlocal
exit /B

Batch to output a list of dates from given for /L parameter

Please consider the following codes:
#echo off
setlocal enabledelayedexpansion
FOR /L %%G IN (0,1,19) DO (
set /a "Dday=%_day%+%%G"
if %mth% equ sml (
if !Dday! gtr 30 (
set "_day=1"
set /a "_month+=1"
)
if !_month! gtr 12 (
set "_month=1"
set /a "_year+=1"
)
) else (
if %mth% equ big (
if !Dday! gtr 31 (
set "_day=1"
set /a "_month+=1"
)
if !_month! gtr 12 (
set "_month=1"
set /a "_year+=1"
)
)
)
echo !Dday!/!_month!/!_year!.txt
)
Consider the following date: 20/04/2016
_day = 20; _month = 04; _year = 2016; mth=sml;
and my output is this:
It increases the day from 30 instead of changing it to 1. Can I know what have I done wrong? Please advise. Thanks
There are two problems in this script. First as #SomethignDark pointed out, you need to use !_day! instead of %_day%.
Second when Dday is greater than 30, %%G is 12. So you expression of !_day!+%%G will be 13 instead of 1.
So you need something like
...
FOR /L %%G IN (0,1,19) DO (
set /a "Dday=!_day!+%%G"
if !_day! equ 1 set /a "Dday=!_day!+%%G-12"
...
You know, pure batch is really cumbersome with date math. What will you do for months with 31 days? For February? During leap year? You should consider, if not altogether switching to another language with a proper date object, then at least borrowing from one. Here's a Batch + PowerShell hybrid example:
<# : batch portion
#echo off & setlocal
if "%~1"=="" (
echo usage: %~nx0 startdate
goto :EOF
)
set "startdate=%~1"
set "daysToAdd=19"
rem # evaluate PowerShell hybrid code and capture output as %%I
for /f "delims=" %%I in ('powershell -noprofile "iex (${%~f0} | out-string)"') do (
rem # do something useful with %%I here
echo %%I.txt
)
goto :EOF
: end batch / begin PowerShell hybrid code #>
# cast "startdate" environment variable value as a datetime object
[datetime]$d = $env:startdate
for ($i = 0; $i -le $env:daysToAdd; $i++) {
$d.addDays($i).toString("dd-MM-yyyy")
}
Or if you prefer the speed of VBScript, here's a Batch + VBScript hybrid example. Its allowed date input is perhaps not quite as flexible as that of PowerShell, but it does execute nearly instantly.
<!-- : batch portion
#echo off & setlocal
if "%~1"=="" (
echo usage: %~nx0 startdate
goto :EOF
)
set "startdate=%~1"
set "daysToAdd=19"
rem # evaluate VBScript hybrid code and capture output as %%I
for /f "delims=" %%I in ('cscript /nologo "%~f0?.wsf" "%startdate%" "%daysToAdd%"') do (
rem # do something useful with %%I here
echo %%I.txt
)
goto :EOF
: end batch / begin VBScript -->
<job>
<script language="VBScript">
if not IsDate(WSH.Arguments(0)) then
WSH.StdErr.WriteLine("Not a valid date.")
WSH.Quit(1)
end if
d = CDate(WSH.Arguments(0))
For i = 0 to WSH.Arguments(1)
d2 = DateAdd("d", i, d)
WSH.Echo(Day(d2) & "-" & Month(d2) & "-" & Year(d2))
Next
</script>
</job>
Or if you're more comfortable with JavaScript syntax, you could do a Batch + JScript hybrid solution.
#if (#CodeSection == #Batch) #then
#echo off & setlocal
if "%~1"=="" (
echo usage: %~nx0 startdate
goto :EOF
)
set "startdate=%~1"
set "daysToAdd=19"
rem // evaluate VBScript hybrid code and capture output as %%I
for /f "delims=" %%I in (
'cscript /nologo /e:JScript "%~f0" "%startdate%" "%daysToAdd%"'
) do (
rem // do something useful with %%I here
echo %%I.txt
)
goto :EOF
#end // end batch / begin JScript
Date.prototype.addDays = function(num) {
this.setDate(this.getDate() + num);
return this;
}
for (var i=0; i<WSH.Arguments(1); i++) {
var d = new Date(WSH.Arguments(0)).addDays(i);
WSH.Echo([d.getDate(), (d.getMonth() + 1), d.getFullYear()].join('-'));
}
Either way, VBScript, JScript, and PowerShell will all let you add n days to a date object, and that date object automatically handles calendar quirks without your explicitly needing to script for them.

Windows Bat Del old files

i have writing a window batch to del the files order than 3 months in some directory, however, there are some problem on :Loop_Folder_Del_Old_Files. I don't know why i cannot assign the last modified date of the files, please help to find out the problem. Below are the source code and program result, thanks!
Source Code
:program_start
#ECHO ON
echo program_start
:Parameter_Settings
set filePath=c:\New Folder
set delPeriod=3
echo %date%
set curYYYY=%date:~10,4%
set curMM=%date:~7,2%
set curDD=%date:~4,2%
:Set_The_Date_Of_3_Months_Ago
set /A curMM=curMM - %delPeriod%
if "%curMM%" LEQ "0" (
set /A curMM="(curMM + 12 - %delPeriod%)%%12"
if %curMM% == 0 (set curMM=12) ELSE (set curMM=%curMM%)
set /A curYYYY=curYYYY - 1
)
set curMM=00%curMM%
set curMM=%curMM:~-2%
set curDate=%curYYYY%%curMM%%curDD%
:Loop_Folder_Del_Old_Files
for %%a IN ("%filePath%\*.*") DO (
set ltdate=%%~ta
set fileDate=%ltdate:~6,4%%ltdate:~3,2%%ltdate:~0,2%
if "%fileDate%" LSS "%curDate%" Del /Q "%%a"
)
:end
echo program end
pause
Result
C:\>echo program_start
program_start
C:\>set filePath=c:\New Folder
C:\>set delPeriod=3
C:\>echo Fri 22/11/2013
Fri 22/11/2013
C:\>set curYYYY=2013
C:\>set curMM=11
C:\>set curDD=22
C:\>set /A curMM=curMM - 3
C:\>if "8" LEQ "0" (
set /A curMM="(curMM + 12 - 3)%12"
if 8 == 0 (set curMM=12 ) ELSE (set curMM=8 )
set /A curYYYY=curYYYY - 1
)
C:\>set curMM=008
C:\>set curMM=08
C:\>set curDate=20130822
C:\>for %a IN ("c:\New Folder*.*") DO (
set ltdate=%~ta
set fileDate=~6,4%ltdate:~3,2%ltdate:~0,2
if "" LSS "20130822" Del /Q "%a"
)
C:\>(
set ltdate=22/11/2013 05:36 PM
set fileDate=~6,4%ltdate:~3,2%ltdate:~0,2
if "" LSS "20130822" Del /Q "c:\New Folder\New Text Document (2).txt"
)
C:\>(
set ltdate=22/11/2013 05:36 PM
set fileDate=~6,4%ltdate:~3,2%ltdate:~0,2
if "" LSS "20130822" Del /Q "c:\New Folder\New Text Document.txt"
)
C:\>echo program end
program end
C:\>pause
Press any key to continue . . .
maybe the use of forfiles to delete old files could be better in handle?
You need to enable delayed expansion to make your variables work inside the for loop.
Add
setlocal enabledelayedexpansion
at the top of your bat file
and then, refer to the variable using the !var! syntax (instead of %var%)
if "!fileDate!" LSS "!curDate!" Del /Q "%%a"
Further to PA's correct response,
set /A curMM=curMM - %delPeriod%
if "%curMM%" LEQ "0" (
set /A curMM="(curMM + 12 - %delPeriod%)%%12"
if %curMM% == 0 (set curMM=12) ELSE (set curMM=%curMM%)
set /A curYYYY=curYYYY - 1
)
Is unreliable as currMM may be 08 or 09 which would generate a syntax-error as batch assumes that any numeric starting with 0 is OCTAL.
set /A curMM=1%curMM% - 100 - %delPeriod%
if %curMM% LEQ 0 (
set /A curMM=curMM + 12
set /A curYYYY=curYYYY - 1
)
is better. The comparison is executed against the NUMERIC value, not a string value. The value of curMM would be 0 for Dec, -1 for Nov, etc - so simply adding 12 and subtracting 1 from the year is sufficient and clearer.

Sorting a text file by date with windows batch script

I have in interesting issue, I need to sort a list of items BY DATE in a text file which look like this:
http://www.boatus.com/sailing,1/21/2013 9:00 PM
http://www.boatus.com/powerboat,3/21/2012 10:00 PM
http://www.boatus.com/games.html,5/20/2013 10:00 PM
http://www.boatus.com/,4/11/2013 10:00 PM
http://www.boatus.com/pressroom/prrss.asp,4/21/2013 10:00 PM
http://www.boatus.com/,4/20/2013 9:00 PM
I also only need say 100 days of history. So if today is 5/10/2013, I only want from 1/30/2013 - 5/10/2013. Hence the list above should then look like this after sorting :
http://www.boatus.com/,4/11/2013 10:00 PM
http://www.boatus.com/,4/20/2013 9:00 PM
http://www.boatus.com/pressroom/prrss.asp,4/21/2013 10:00 PM
http://www.boatus.com/games.html,5/20/2013 10:00 PM
Hence only the past 100 days are listed in order by date.
Try this (list is in file.txt):
#echo off &setlocal
for /f "tokens=1*delims=[] " %%x in ('^<file.txt find /n /v ""') do (
for /f "tokens=2delims=, " %%j in ("%%y") do (
for /f "tokens=1-3delims=/" %%a in ("%%j") do (
if %%a lss 10 if %%b lss 10 set "$%%c0%%a0%%b%%x=%%y"
if %%a lss 10 if %%b geq 10 set "$%%c0%%a%%b%%x=%%y"
if %%a geq 10 if %%b lss 10 set "$%%c%%a0%%b%%x=%%y"
)
)
)
for /f "tokens=1-4delims=/ " %%i in ("%date%") do set /a month=1%%j-100, day=1%%k-100, year=%%l
if %month% lss 10 set "month=0%month%"
if %day% lss 10 set "day=0%day%"
call:DateToJDN %year%%month%%day% today
setlocal enabledelayedexpansion
for /f "tokens=1*delims=$=" %%i in ('set "$"') do (
if defined today (
call:DateToJDN %%i uday
set /a diffdays=today-uday
if !diffdays! leq 100 set "today="&echo(%%j
) else echo(%%j
)
endlocal
goto:eof
:DateToJDN yyyymmdd jdn=
setlocal
set date=%1
set /A yy=%date:~0,4%, mm=1%date:~4,2% %% 100, dd=1%date:~6,2% %% 100
set /A a=mm-14, jdn=(1461*(yy+4800+a/12))/4+(367*(mm-2-12*(a/12)))/12-(3*((yy+4900+a/12)/100))/4+dd-32075
endlocal & set %2=%jdn%
exit /B
Edit: added code improvements concerning Peter Wright's comment
JDN
Here's my version since I've written it - I didn't bother about the 'last 100 days' part which makes it easy if you change your mind.
#ECHO OFF
SETLOCAL enabledelayedexpansion
(
FOR /f "tokens=1*delims=, " %%h IN (swydf.txt) DO (
FOR /f "tokens=1-7delims=/: " %%a IN ("%%i") DO (
SET /a rmonth=10+%%a
SET /a rday=10+%%b
SET /a rhour=10+%%d
IF %%d==12 (SET rhour=10)
ECHO %%c!rmonth!!rday!%%f!rhour!%%e,%%h,%%i
)
)
)>sorttemp.txt
(
FOR /f "tokens=1*delims=," %%i IN ('sort ^<sorttemp.txt') DO ECHO %%j
)>output.txt
TYPE output.txt
DEL sorttemp.txt /F /Q
GOTO :eof
Essentially, the date and time elements are converted to a constant-length field each by adding 10 (since all bar minutes are 1..31 - making 11..41) then setting hour to 10 if it's 12 (thus 12AM->10 sorts before 1AM->11)
Sort the result of YEAR+MONTH+DAY+AMPM+HOUR+MIN+,+HTTP...+,+data and output the remainder after the first token (delimited by comma)
if the data you are sorting is already in text form I think you could copy and paste to a new excel doc and sort by date
My code at the moment, thanks guys for your help so far !!!! I still need it to change date format to YYYYMMDD, something wrong with the code.. grrr
#ECHO OFF
SETLOCAL enabledelayedexpansion
for /f "tokens=1-3delims=/" %%i in ("%date:~4,10%") do set /a month=%%i, day=%%j, year=%%k
if %month% lss 10 set "month=0%month%"
if %day% lss 10 set "day=0%day%"
call:DateToJDN %year%%month%%day% today
echo Today %today% %year%%month%%day%
(
FOR /f "tokens=1*delims=, " %%h IN (file.txt) DO (
FOR /f "tokens=1-7delims=/: " %%a IN ("%%i") DO (
SET /A RMONTH=100+%%a, RDAY=100+%%b
SET /a RHOUR=%%d+100
IF %%d==12 SET RHOUR=100
call:DateToJDN %%c!RMONTH:~1!!RDAY:~1! rtoday
REM call:DateToJDN %%c%%a%%b rtoday
set /a diffdays=!today!-!rtoday!
REM echo diffdays === !today!-!rtoday! = !diffdays!
if !diffdays! leq 100 (
ECHO %%c!rmonth!!rday!%%f!rhour!%%e,%%h,%%i
)
)
)
)>sorttemp.txt
(
FOR /f "tokens=1*delims=," %%i IN ('sort ^<sorttemp.txt') DO ECHO %%j
)>output.txt
TYPE output.txt
::: DEL sorttemp.txt /F /Q
notepad sorttemp.txt
GOTO :eof
:DateToJDN yyyymmdd jdn=
setlocal
set date=%1
REM echo %date%
set /A yy=%date:~0,4%, mm=1%date:~4,2% %% 100, dd=1%date:~-2% %% 100
set /A a=mm-14, jdn=(1461*(yy+4800+a/12))/4+(367*(mm-2-12*(a/12)))/12-(3*((yy+4900+a/12)/100))/4+dd-32075
endlocal & set %2=%jdn%
exit /B
endlocal

Resources