Batch to archive files - batch-file

I am making a script that can allow me to archive all files of a given directory whom last modified date is superior to 30 days.
The files should be moved to a new folder and this folder must be zipped afterwards.
Aditionaly - and this is a bit crutial - in the archiving process, the files should be grouped by month. The name of the zipped folder should indicate the month and year of the contained files.
Example:
2012_12.zip (contains all files from December 2012) ;
2013_01.zip (contains all files from January 2013)
This is what I have so far:
ECHO OFF
ECHO.
SET /p folder=Which folder you want to archive?
ECHO.
ECHO %folder%
CHDIR %folder%
MKDIR Archive
ROBOCOPY "%folder%" "%folder%\Arquivo" /E /V /ETA /MOVE /XD "%folder%\Archive"
:: Exclude files newer than 30 days
FORFILES /P "%folder%\Archive" /D -31/12/2012 /D +1/12/2012 /C GOTO :ZIP
CALL:ZIP
SET filetozip="%folder%\Archive"
set tempdir=C:\Users\tiago.campos\Documents\OMS\FilesArchiver\tempdir
mkdir %tempdir%
copy %filetozip% %tempdir%
mkdir "%filetozip%\Archive"
rmdir %tempdir%
realdate
echo Set objArgs = WScript.Arguments > _zipIt.vbs
echo InputFolder = objArgs(0) >> _zipIt.vbs
echo ZipFile = objArgs(1) >> _zipIt.vbs
echo CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" ^& Chr(5) ^& Chr(6) ^& String(18, vbNullChar) >> _zipIt.vbs
echo Set objShell = CreateObject("Shell.Application") >> _zipIt.vbs
echo Set source = objShell.NameSpace(InputFolder).Items >> _zipIt.vbs
echo objShell.NameSpace(ZipFile).CopyHere(source) >> _zipIt.vbs
echo wScript.Sleep 2000 >> _zipIt.vbs
CScript _zipIt.vbs %tempdir% "%filetozip%\Archive\2013.01.zip"
del "_zipIt.vbs"
pause
As a bonus feature, it would be very useful if instead of giving the directory as an input, the script would read from a csv file with more than one directory.
I'm a bit lost in the momement.
I thank in advance for every reply!

Since you're already using vbscript for zipping and vbscript is also better for performing arithmetic with dates, might as well do the whole thing in vbscript.
I didn't do the csv thing, but maybe you could call the script with a batch for %%I in (csvfile) do cscript /nologo archive.vbs %%I or similar. If no argument is passed, it archives the current working directory.
' archive.vbs
' usage: cscript archive.vbs (directory, optional)
if not wscript.arguments.count then
dir = left(WScript.ScriptFullName,(Len(WScript.ScriptFullName))-(len(WScript.ScriptName)))
else
dir = wscript.arguments(0)
if not Right(dir, 1) = "\" then
dir = dir & "\"
end if
end if
set fso = createobject("scripting.filesystemobject")
set shl = createobject("shell.application")
set osh = createobject("wscript.shell")
set files = fso.getFolder(dir).files
dim zips
dim folders
redim zips(-1)
redim folders(-1)
for each file in files
if DateDiff("d", file.datelastmodified, Date()) > 30 then
yyyymm = DatePart("yyyy", file.datelastmodified) & "_" & Right("0" & DatePart("m", file.datelastmodified), 2)
dest = dir & yyyymm & "\"
if not fso.folderexists(dest) then
fso.createFolder dest
zip = dir & yyyymm & ".zip"
redim preserve zips(ubound(zips) + 1)
redim preserve folders(ubound(folders) + 1)
zips(ubound(zips)) = zip
folders(ubound(folders)) = dest
end if
Wscript.echo "Moving " & file & " to " & dest
fso.moveFile file, dest
end if
next
set files = nothing
Wscript.echo "Copying finished."
on error resume next
for i = lbound(zips) to ubound(zips)
Wscript.echo i & ": Zipping " & folders(i) & " to " & zips(i)
set zip = fso.createtextfile(zips(i))
zip.write "PK" & chr(5) & chr(6) & string(18, chr(0))
zip.close
set zip = Nothing
shl.namespace(zips(i)).copyhere shl.namespace(folders(i)).items
do until shl.namespace(zips(i)).items.count = shl.namespace(folders(i)).items.count
wscript.sleep 100
loop
' This method of deleting folders is more reliable than fso.deletefolder
' for paths with long filenames.
osh.run "cmd /c rmdir /q /s """ & folders(i) & """", 1, true
next
Wscript.Echo "Done."

Related

How can I save addresses from batch file to text?

I want to save this code from batch file to txt but cant.
I write this code but this code not working, cant save the address
how can i save "some code" like this from batch file to txt.
i have many codes and need to save it at the right time from batch file to txt and not execute them just save as txt.
tnq
this code want to save:
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run chr(34) & "C:\Program Files\Windows Task\WindowsTask.bat" & Chr(34), 0
Set WshShell = Nothing
this is my solution and not working:
#echo off
(echo Set WshShell = CreateObject^("WScript.Shell"^) )> sina.txt
(echo WshShell.Run chr^(34^) & "C:\Program Files\Windows Task\WindowsTask.bat" & Chr^(34^), 0) >> sina.txt
(echo Set WshShell = Nothing) >> sina.txt
pause
You have far less trouble with paranthesis and escaping if you put the redirection at the beginning of the line.
#echo off
> sina.txt echo Set WshShell = CreateObject("WScript.Shell")
>> sina.txt echo WshShell.Run chr(34) ^& "C:\Program Files\Windows Task\WindowsTask.bat" ^& Chr(34), 0
>> sina.txt echo Set WshShell = Nothing
pause
You need to double the %.
>> sina2.txt echo SET TodayYear=%%DATE:~10,4%%
The result in your file will be:
SET TodayYear=%DATE:~10,4%

How can I create and combine "InstallDate" Output with "xxx Days Ago" in batch?

Below mentioned batch file displays InstallDate (Converted):
#echo off
for /f "delims=" %%A in ('WMIC OS GET InstallDate /format:value') do (
#for /f "tokens=2 delims==" %%B in ("%%A") do (
Call :ConvertDate %%B
)>"%temp%\%~n0.txt"
)
for /f "delims=" %%D in ('Type "%temp%\%~n0.txt"') do ( set InstallDate=%%D )
echo Install Date: %InstallDate%
pause
::**********************************************************************
Rem Function for Converting WMI Dates to a Standard Date-Time Format
:ConvertDate <Date>
(
echo WScript.echo WMIDateStringToDate("%~1"^)
echo Function WMIDateStringToDate(Mydate^)
echo WMIDateStringToDate = CDate(Mid(Mydate, 5, 2^) ^& "/" ^& _
echo Mid(Mydate, 7, 2^) ^& "/" ^& Left(Mydate, 4^) _
echo ^& " " ^& Mid (Mydate, 9, 2^) ^& ":" ^& _
echo Mid(Mydate, 11, 2^) ^& ":" ^& Mid(Mydate,13, 2^)^)
echo End Function
)>"%temp%\%~n0.vbs"
cscript /nologo "%temp%\%~n0.vbs" "%~1"
Del "%temp%\%~n0.vbs"
exit /b
Output:
Install Date: 24/05/2020 12:54:28
Now, For this I am trying to create and combine Desire Output like:
Install Date: 24/05/2020 12:54:28 (114 Days Ago)
I have tried several things but failed. is there any way to do this in batch?
Thanks.
As you're already using wsh for your date conversion, you may as well use it to retrieve the wmi information too.
Here's a single hybrid batch-file which should do that for you, without the need to write a vbs file, run it, then delete it:
<!-- :
#"%__APPDIR__%cscript.exe" //NoLogo "%~f0?.wsf"
#Pause & GoTo :EOF
-->
<Job><Script Language="VBScript">
On Error Resume Next
Set objWMIService = GetObject("winmgmts://./root/cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem",,48)
For Each objItem in colItems
dtmInstalled = ParseDat(objItem.InstallDate)
numInstalled = DateDiff("n",dtmInstalled,ParseDat(objItem.LocalDateTime))
numInstDays = (numInstalled \ 60) \ 24
strMessage = "Install Date: " & dtmInstalled
If numInstDays = 0 Then
strMessage = strMessage & " (Today)"
ElseIf numInstDays > 1 Then
strMessage = strMessage & " (" & numInstDays & " Days Ago)"
Else
strMessage = strMessage & " (" & numInstDays & " Day Ago)"
End If
Next
WScript.Echo strMessage
WScript.Quit
Function ParseDat(ByVal strDate)
strYear = Left(strDate,4)
strMonth = Mid(strDate,5,2)
strDay = Mid(strDate,7,2)
strDat = strDay & "/" & strMonth & "/" & strYear
strHour = Mid(strDate,9,2) - strTimeShift
strMins = Mid(strDate,11,2)
strSecs = Mid(strDate,13,2)
strTime = strHour & ":" & strMins & ":" & strSecs
ParseDat = strDat & " " & strTime
End Function
</Script></Job>
As you've made no attempt at calculating the number of days yourself, I will not be explaining any of the above, modifying it, or adjusting it should you decide to modify your question post submission.

How to get particular code as output from a text file using batch?

I have a text file with a youtube link,
text file = url.txt , which consist,
https://www.youtube.com/watch?v=Videocode
my need is, by running a batch file how to get only that Videocode as output in another text file.
For example, if am running url.bat which need to convert "https://www.youtube.com/watch?v=Videocode" into "Videocode"
I hope you understand my need. Please gave me some solutions. Thanks in advance.
Taking the question as asked literally, a text file named url.txt containing a link in the format https://www.youtube.com/watch?v=Videocode, url.bat could just contain this:
#For /F "UseBackQ Tokens=2 Delims==&" %%A In ("C:\Users\niranja\Desktop\url.txt") Do #(Echo %%A)>"output.txt"
Change the path to your url.txt, C:\Users\niranja\Desktop\, to suit; or if it is in the same location as url.bat remove that path completely. The video ID you were looking for should be written to a file named output.txt in the same directory as url.bat.
Note: If question as written does not match your real intent, take a look at the link provided by Hackoo and start putting something together yourself!
Here is an idea with a vbscript using a Regex to extract the "Videocode"
Data = "https://www.youtube.com/watch?v=Videocode" & vbCrlf &_
"http://www.youtube.com/watch?v=iwGFalTRHDA" & vbCrlf &_
"http://www.youtube.com/watch?v=iwGFalTRHDA&feature=related" & vbCrlf &_
"http://youtu.be/iwGFalTRHDA" & vbCrlf &_
"http://youtu.be/n17B_uFF4cA" & vbCrlf &_
"http://www.youtube.com/embed/watch?feature=player_embedded&v=r5nB9u4jjy4" & vbCrlf &_
"http://www.youtube.com/watch?v=t-ZRX8984sc" & vbCrlf &_
"http://youtu.be/t-ZRX8984sc"
Data_Extracted = Extract(Data,"http(?:s?):\/\/(?:www\.)?youtu(?:be\.com\/watch\?v=|\.be\/)([\w\-\_]*)(&(amp;)?‌​[\w\?‌​=]*)?")
WScript.echo Data_Extracted
'************************************************
Function Extract(Data,Pattern)
Dim oRE,oMatches,Match,Line
set oRE = New RegExp
oRE.IgnoreCase = True
oRE.Global = True
oRE.Pattern = Pattern
set oMatches = oRE.Execute(Data)
If not isEmpty(oMatches) then
For Each Match in oMatches
Line = Line & Match.SubMatches(0) & vbcrlf
Next
Extract = Line
End if
End Function
'************************************************
EDIT : Using an hybrid code batch with a vbscript
#echo off
Title Extract Videocode from Youtube links
Set "Tmpvbs=%temp%\Tmpvbs.vbs"
Set "InputFile=URL.txt"
Set "OutPutFile=OutPutCode.txt"
Call :Extract "%InputFile%" "%OutPutFile%"
Start "" "%OutPutFile%" & exit
::****************************************************
:Extract <InputData> <OutPutData>
(
echo Data = WScript.StdIn.ReadAll
echo Data = Extract(Data,"http(?:s?):\/\/(?:www\.)?youtu(?:be\.com\/watch\?v=|\.be\/^)([\w\-\_]*)(&(amp;)?‌​[\w\?‌​=]*)?"^)
echo WScript.StdOut.WriteLine Data
echo '************************************************
echo Function Extract(Data,Pattern^)
echo Dim oRE,oMatches,Match,Line
echo set oRE = New RegExp
echo oRE.IgnoreCase = True
echo oRE.Global = True
echo oRE.Pattern = Pattern
echo set oMatches = oRE.Execute(Data^)
echo If not isEmpty(oMatches^) then
echo For Each Match in oMatches
echo Line = Line ^& Match.SubMatches(0^) ^& vbcrlf
echo Next
echo Extract = Line
echo End if
echo End Function
echo '************************************************
)>"%Tmpvbs%"
cscript /nologo "%Tmpvbs%" < "%~1" > "%~2"
If Exist "%Tmpvbs%" Del "%Tmpvbs%"
exit /b
::**********************************************************************************

batch find and replace

this is my problem:
on a Windows 2003 server I've a folder (c:\test), and every day an application put 3 new files on it.
1° file:
31201610181207000100000000630001
31201610181213000100000000440001
31201610181227000100000000630001
....
2° file:
31201610181214000100000000380002
31201610181234000100000009830002
31201610181344000100000000380002
...
3° file:
31201610181826000100000000580003
31201610190722000100000000580003
31201610191801000100000000580003
...
My goal is to replace ONLY the last 4 characters on each file with a .bat or .vbs script (0001 --> 0031) (0002 --> 0032) (0003 --> 0033).
I've done a .vbs file who works, but it search on all string and not on the last 4 characters.
Option Explicit
Dim objFSO, strFolder, objFolder, objFile
Dim strOldValue1, strNewValue1, strNewValue2, strOldValue2, strNewValue3,
strOldValue3, objRead, strContents, objWrite
Const ForReading = 1
Const ForWriting = 2
strFolder = "c:\test"
strOldValue1 = "0001"
strNewValue1 = "0031"
strOldValue2 = "0002"
strNewValue2 = "0032"
strOldValue3 = "0003"
strNewValue3 = "0033"
' I take the folder
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(strFolder)
' I count the file on the folder
For Each objFile In objFolder.Files
' Read file with textstream object.
Set objRead = objFSO.OpenTextFile(objFile.Path, ForReading)
' Trap error if file is empty or cannot read.
On Error Resume Next
strContents = objRead.readall
If (Err.Number <> 0) Then
On Error GoTo 0
Wscript.Echo "Cannot read: " & objFile.Path
strContents = ""
End If
On Error GoTo 0
objRead.Close
' check what's is inside the folder
If (InStr(strContents, strOldValue1) > 0) Then
strContents = Replace(strContents, strOldValue1, strNewValue1)
Set objWrite = objFSO.OpenTextFile(objFile.Path, ForWriting)
objWrite.Write strContents
objWrite.Close
End If
If (InStr(strContents, strOldValue2) > 0) Then
strContents = Replace(strContents, strOldValue2, strNewValue2)
Set objWrite = objFSO.OpenTextFile(objFile.Path, ForWriting)
objWrite.Write strContents
objWrite.Close
End If
If (InStr(strContents, strOldValue3) > 0) Then
strContents = Replace(strContents, strOldValue3, strNewValue3)
Set objWrite = objFSO.OpenTextFile(objFile.Path, ForWriting)
objWrite.Write strContents
objWrite.Close
End If
next
Thanks for any help!!
Here is a short batch script, which immediately modifies all files C:\test\*.* accordingly:
for %%F in ("C:\test\*.*") do (
for /F "delims=" %%L in ('type "%%~F" ^& ^> "%%~F" rem/') do (
set "LINE=%%L"
setlocal EnableDelayedExpansion
set "LEFT=!LINE:~,-4!"
set "RIGHT=!LINE:~-4!"
if "!RIGHT!"=="0001" set "RIGHT=0031"
if "!RIGHT!"=="0002" set "RIGHT=0032"
if "!RIGHT!"=="0003" set "RIGHT=0033"
>> "%%~F" echo(!LEFT!!RIGHT!
endlocal
)
)
Using JREPL.BAT - a regular expression find/replace utility
for %%F in (c:\test\*) do call jrepl "000(?=[123]$)" "003" /f "%%F" /o -
The above looks at the end of each line for "000" before a "1", "2", or "3", and substitutes "003" for the "000".
JREPL is pure script (hybrid batch/JScript) that runs natively on any Windows machine from XP onward - No 3rd party exe file required.
Thank you very much!!!! it works!!
Also, if you're interested I've found how the make my script work:
I've to add the & VBCrlf to the variable, in this way the script will search for the value + the new line.
strOldValue1 = "0001" & VBCrlf
strNewValue1 = "0031" & VBCrlf
strOldValue2 = "0002" & VBCrlf
strNewValue2 = "0032" & VBCrlf
strOldValue3 = "0003" & VBCrlf
strNewValue3 = "0033" & VBCrlf

windows ".lnk" shortcuts and batches don't mix

I have a batch file which is used by dragging a folder containing .mp3s into the batch.
#echo off
cd %~dp0
setlocal enabledelayedexpansion enableextensions
set FLDR="%1"
if not defined FLDR ( echo Drag a folder to the batch to play its contents.
pause
goto:EOF )
for %%x in (%FLDR%\*.mp3) do set "MP3=!MP3! "%%x""
mp3player %MP3%
pause
It works fine with actual folders, but when dragging shortcuts, the variable %FLDR% ends up as "c:\link location\folder.lnk" instead of the actual folder location.
I have no idea how to get around this.
Here is a way to get the target using a little hybrid VBS/Batch file function.
#echo off
setlocal
Call :GetTarget "%~1" tgt
echo %tgt%
pause
exit /b
:GetTarget
#echo off & setlocal
set gt=%temp%\_.vbs
echo set WshShell = WScript.CreateObject("WScript.Shell")>%gt%
echo set Lnk = WshShell.CreateShortcut(WScript.Arguments.Unnamed(0))>>%gt%
echo wscript.Echo Lnk.TargetPath>>%gt%
set script=cscript //nologo %gt%
For /f "delims=" %%a in ( '%script% "%~1"' ) do set target=%%a
del %gt%
endlocal & set %~2=%target%
exit /b
HYBRID SCRIPT! No silly little temporary files.
::'<SUB>#echo off
::'<SUB>set shortcut=%~1
::'<SUB>if not defined shortcut goto 'usage
::'<SUB>if not %shortcut:~-4%==.lnk (if not %shortcut:~-4%==.url (set errorlevel=1
::'<SUB>goto 'usage ))
::'<SUB>if not exist %shortcut% (echo Error: Nonexistent shortcut
::'<SUB>set errorlevel=1
::'<SUB>goto:EOF )
::'<SUB>setlocal
::'<SUB>for /f "delims=" %%T in ('cscript //nologo //e:vbs %~nx0 "%shortcut%"') do set thing=%%T
::'<SUB>endlocal & set shortcut=%thing%
::'<SUB>goto:EOF
:'usage
::'<SUB>echo command-line shortcut redirect utility
::'<SUB>echo Usage: shortcut [file.lnk ^| file.url]
::'<SUB>echo The resulting link will be output to the %%shortcut%% variable.
::'<SUB>goto:EOF
set WshShell = WScript.CreateObject("WScript.Shell")
set Lnk = WshShell.CreateShortcut(WScript.Arguments.Unnamed(0))
wscript.Echo Lnk.TargetPath
Where <SUB> indicates the substitute character.
UPDATE: I found a much fully vbscript solution over at Wayne's World of IT, and modified it slightly to suit my needs:
If WScript.Arguments.UnNamed.Count = 1 Then
strShortcut = WScript.Arguments.UnNamed(0)
Else
WScript.Echo "Please supply the name of an lnk file or directory to read, eg c:\test.lnk or c:\shortcuts"
WScript.Quit(1)
End If
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FolderExists(strShortCut) Then
Set objFolder = objFSO.getFolder(strShortcut)
For Each objfile in objFolder.Files
If objfile.type = "Shortcut" Then
Call Readshortcut(objFile.Path, strProperties)
dtmCreationDate = objFile.DateCreated
WScript.Echo dtmCreationDate & "," & strProperties
End If
Next
ElseIf objFSO.FileExists(strShortCut) Then
Call Readshortcut(strShortcut, strProperties)
WScript.Echo strProperties
Else
WScript.Echo "Error: Could not read '" & strShortcut & "'"
WScript.Quit(2)
End If
Set objFSO = Nothing
Function Readshortcut(ByRef strShortcut, ByRef strProperties)
set objWshShell = WScript.CreateObject("WScript.Shell")
set objShellLink = objWshShell.CreateShortcut(strShortcut)
strProperties = objShellLink.TargetPath & " " & objShellLink.Arguments
Set objShellLink = Nothing
Set objWshshell = Nothing
End Function

Resources