How to add zero to single digit in a string - vbscript

I need to to append zero in my below string whenever I get date with single digit without changing Quantity digit (below string is system generated in my application not created by user),
Data Added Quantity:1 on Dec 9 2015 modified on Jun 7 2016
I need to change this string just like below,
Data Added Quantity:125 on Dec 09 2015 modified on Jun 07 2016
So far I have tried the below regular expression, but not getting desired output.
str = "Data Added Quantity:1 on Dec 9 2015 modified on Jun 7 2016"
Set oReg = New RegExp
oReg.Pattern = "\s\d{1}\s"
Set obj = oReg.Execute(str)
For i = 0 To obj.Count-1
mD = obj.Item(i).Value
oReg.Replace(str, "0" & mD)
Next
How we can achieve this using VBScript?

If you adjust the pattern a little and set the Global option to True you can simply use the Replace method. No need to Excecute and loop.
Set re = New RegExp
re.Pattern = "\s(\d)\s"
re.Global = True
str = re.Replace(str, " 0$1 ")
\d without a modifier already matches exactly one digit, so \d{1} is redundant. The parentheses around the \d define a capturing group that allows you to use the matched substring in the replacement ($1).

Related

Cannot convert my variables to CDate or Serial Date, getting Mismatch error [duplicate]

This question already has answers here:
UTC time stamp format - Split in parts a string containing the UTC time date (classic asp/vbscript)
(2 answers)
Closed 1 year ago.
I've ready numerous posts here about the mismatch error but every format I try I still get the same error.
Dim calendarDate, sDate, sFinal
calendarDate = "Sun Apr 05 00:00:00 CDT 2020"
sYear = Right(calendarDate, 4)
sDay = Mid(calendarDate,9,2)
sMonth = Mid(calendarDate,5,3)
If sMonth = "Apr" Then sMonth = "04" Else sMonth = sMonth
End if
sDate = sYear & "-" & sMonth & "-" & sDay
sFinal = CDate(sDate)
I get the type mismatch CDate error but the format should work? I have also tried MM/DD/YYYY.
And I have tried sFinal = DateSerial(sYear,sMonth,SDay) also does not work. But if you don't use the variables...
sFinal = DateSerial("2020","04","05") this works. I don't understand why my SYear, SMonth, SDay would not work as they are the same numbers."
My end goal here is to subtract 14 days from the calendar date but i can't even get my variable into a date format to subtract it...so maybe there is something simpler I should be doing here?
Thank you all for any help you can give much appreciated! Long time reader, first time posting.
The simplest way to manipulate will be to use Split() as each value separated by a Space (Chr(32)).
What you end up with is an array containing each element that made up the string split by the Space character (Chr(32)), so by concatenating values back together we can construct our date-time how CDate() expects, excluding the first and sixth element which will be Sun and CDT respectively, as well as re-ordering the year in the constructed string that is passed to CDate().
Dim input: input = "Sun Apr 05 00:00:00 CDT 2020"
Dim data: data = Split(input, Chr(32))
'Ignore first and sixth element in the array and build our date value
Dim output: output = CDate(data(1) & " " & data(2) & " " & data(5)) & " " & TimeValue(data(3))
Call Wscript.Echo(output)
Output:
05/04/2020 00:00:00
Note: Result will be based on the user's regional settings as CDate() uses this while parsing a Date string.
Useful Linkss
UTC time stamp format - Split in parts a string containing the UTC time date (classic asp/vbscript) (Example of parsing date string).

Graylog , Handle files before store it

I am trying to create log system using Gray log,
I have logs like this
Mon Aug 17 16:53:10 2020
NAS-IP-Address = 172.20.101.1
User-Name = "netconf"
Acct-Status-Type = Start
Acct-Session-Id = "ACCTID20200817112721000fe14d000000001040717"
Acct-Authentic = RADIUS
NAS-Identifier = "NR-DELHI-NRTCC-CR-01"
Framed-IP-Address = 172.20.16.6
NAS-Port-Type = Virtual
Event-Timestamp = "Aug 17 2020 16:57:21 IST"
Tmp-String-9 = "ai:"
Acct-Unique-Session-Id = "23be63c276bbda95385d118ff93ba298"
Timestamp = 1597663390
Mon Aug 17 16:54:15 2020
NAS-IP-Address = 172.20.101.1
User-Name = "netconf"
Acct-Status-Type = Start
Acct-Session-Id = "ACCTID20200817112825000fe14f000000001040719"
Acct-Authentic = RADIUS
NAS-Identifier = "NR-DELHI-NRTCC-CR-01"
Framed-IP-Address = 172.20.16.6
NAS-Port-Type = Virtual
Event-Timestamp = "Aug 17 2020 16:58:25 IST"
Tmp-String-9 = "ai:"
Acct-Unique-Session-Id = "49fcad388a523e7eebea6043529c323e"
Timestamp = 1597663455
actually, every block is one log record, but the problem is that Graylog considering every line as a separated log, so what I want is to tell Graylog to read every block as one record.
is there any way to do that, some configuration that I have to do in Gray log to achieve my goal.
I have an idea but I am not sure about it, I am thinking about creating a bash script which will read the file and merge lines which belong to one block in one line,
but I am not sure if this method will work or not, so I am wondering if there is any way to do it from Graylog itself.
any suggestion will be appreciate
Best Regards
if messages in the log file begin with a blank line, then you could use the readmode parameter of the imfile module: https://www.rsyslog.com/doc/v8-stable/configuration/modules/imfile.html#readmode

Create monthly trigger for Scheduled Task in Powershell (With additional criteria)

I'm currently working on a script that when run, creates some Scheduled tasks that makes the host machine do several things and then restart within a specified time span.
This script needs to be run on multiple domain controllers, and therefor i would like to "load balance" by using something like New-ScheduledTaskTrigger -RandomDelay in order for them to not reboot all at once, but kind of spread it out.
The goal is to be able to change some variables of when to restart, things like:
First Monday of the month between 18:00 and 23:59
Every Thursday between 01:00 and 06:00
Every day between 04:00 and ..... you see where I'm going
However there is no such thing as a "-Monthly" in New-ScheduledTaskTrigger
That's the first problem, this one i can probably solve with the help from other posts, but if i do it for example like this I'm not able to use the -RandomDelay which I think is a major feature for this to work.
Here is how I imagine it should look if the -Monthly did work (for a monthly trigger):
$rebootFrequency = MONTHLY # DAILY, WEEKLY, MONTHLY
$rebootWeek = FIRST # FIRST, SECOND, THIRD, FOURTH, LAST
$rebootDayOfWeek = MON # MON, TUE, WED, THU, FRI, SAT, SUN
$rebootTimeFrom = 10:00 # HH:MM[:SS]
$rebootTimeTo = 16:00 # HH:MM[:SS]
New-ScheduledTaskTrigger -"$rebootFrequency" -WeekOfMonth $rebootWeek;
-DayOfWeek $rebootDayOfWeek -At $rebootTimeFrom -RandomDelay $rebootTimeTo
Do you have any suggestions as to how I should solve this problem?
I could do the same thing with schtask.exe, however I would end up having to make some kind of script to do the "RandomDelay" function.
Feel free to ask further if you have any questions.
Thanks in advance.
Challenge 1
I've now got it to work, but I'm trying to make the script a bit more intuitive, but I can't figure out how i would do it...
What i want to do is to "convert" from using the numbers in days (for example: 16 for Thursday) to being able to write "THU" instead.
Right now it looks something like this:
$rebootDaysOfWeek = "16" # SUN=1, MON=2, TUE=4, WED=8, THU=16 etc.
$trigger.DaysOfWeek = $rebootDaysOfWeek
But I would find it alot cooler if it was something like this:
$rebootDaysOfWeek = "THU" # SUN, MON, TUE, WED, THU, FRI, SAT
$trigger.DaysOfWeek = $rebootDaysOfWeek
But I can't seem to find a way to "convert" $rebootDaysOfWeek to work with the bit mask.
Check out the Microsoft Docs:
https://learn.microsoft.com/en-us/windows/win32/taskschd/time-trigger-example--scripting-
The sample is in VB, but it looks like it's just a ComObject. I haven't had enough time to play around, but you can start like this:
$service = new-object -comobject Schedule.Service
$service.connect()
$taskdefinitiion = $service.NewTask(0)
There's lots of task definition stuff, but it get's down to the triggers and you'll do this:
$triggers = $taskDefinition.Triggers
$trigger = triggers.Create(5) # I had to try different numbers here, didn't dig through the docs
$trigger.DaysOfWeek = 16 #Thursday
$trigger.WeeksOfMonth = 1 # First week, 2 for second, 6 for third, 8 for forth
$trigger.MonthsOfYear = 4095 # all months
$trigger.RandomDelay = 'PT1H' # 1 hour random delay.
I'll let you take it from here. Links to some of the items above:
https://learn.microsoft.com/en-us/windows/win32/taskschd/monthlydowtrigger-daysofweek
https://learn.microsoft.com/en-us/windows/win32/taskschd/monthlydowtrigger-monthsofyear
https://learn.microsoft.com/en-us/windows/win32/taskschd/monthlydowtrigger-weeksofmonth
https://learn.microsoft.com/en-us/windows/win32/taskschd/monthlydowtrigger-randomdelay
UPDATE FOR CHALLENGE 1
In order to use "friendly" references to the bitwise decimal value you can either create a constants section or use hashtable, either way you are going to have to do the conversion yourself:
# Constants
$SUN = 1
$MON = 2
$TUE = 4
$WED = 8
$THU = 16
$FRI = 32
$SAT = 64
# Hashtable - because why not!
$DaysOfWeek = #{
SUN = 1
MON = 2
TUE = 4
WED = 8
THU = 16
FRI = 32
SAT = 64
}
Then you can use:
$trigger.DaysOfWeek = $THU
or
$trigger.DaysOfWeek = $DaysOfWeek["THU"]

Checking for time

I have a form field which may have a date and may have a time in it. I need to confirm that both a date and time are present.
<input type="text" name="transdate" ... />
I can use isDate(form.transdate) to check if there is a date, but it does not check if there is a time. I wish there was a isTime() function.
Addendum
The date time fields can be made to have
These fields are concatinated via
date_cat = "#form.trans_date# #form.trans_date_h#:#form.trans_date_m# #form.trans_date_t#";
When I run this code:
cat: #date_cat# isValid(date): #isValid('date', date_cat)# isValid(time): #isValid('time', date_cat)#
I get
cat: 12/05/2018 :24 PM isValid(date): YES isValid(time): YES
Some people hate regular expressions. I love them. Why not just check the concatenated string?
dtRegEx = "^(0[1-9]|1[0-2])/(0[1-9]|[1-2][0-9]|3[0-1])/[1-9][0-9]{3} (0[0-9]|1[0-2]):[0-5][0-9] (am|pm)$";
if (reFind(dtRegEx, date_cat) and isDate(date_cat)) {
// valid datetime
} else {
// invalid datetime
}
RegEx Breakdown
^
string has to start with the whole pattern
(0[1-9]|1[0-2])
month in range from 01 to 09 or 10 to 12
/
date delimiter
(0[1-9]|[1-2][0-9]|3[0-1])
day in range from 01 to 09, 10 to 29 or 30 to 31
/
date delimiter
[1-9][0-9]{3}
year in range from 1000 to 9999
space
space, literally
(0[0-9]|1[0-2])
hour in range from 00 to 09 or 10 to 12
:
time delimiter
[0-5][0-9]
seconds in range from 00 to 59
space
space, again
(am|pm)
the meridiem stuff you guys from US and UK like so much :P
$
string has to end with the whole pattern
Note that the above pattern could still have you end up with invalid day ranges like 02/31/2018, that's why you should still check with isDate().
Here is how I addressed it, I validated the fields before the concatenation
if (form.trans_date_h == "" || form.trans_date_m == "" || form.trans_date_t == "") {
// error handling here
Then did the concatenation
date_cat = "#form.trans_date# #form.trans_date_h#:#form.trans_date_m# #form.trans_date_t#";

Ruby string.match() function fails with identical string within the to be matched string

I copied and pasted a smaller portion of a large string and matched it against the large string. However, it does not return the value back. In the NOT case, it returns true. Is there something to the match function I am missing, or could there be hidden characters?
times = File.readlines('timesplit')
stringcomp = "created_at : Tue Jul 02 03:30:50 +0000 2013 id : 351905778745094144 id_str : 351905778745094144"
times.each do |t|
r = t.split('|')
timestamp = r[1]
puts !stringcomp.match(timestamp)
puts stringcomp.match(timestamp)
end
Below are the contents for timesplit.
Jul_01|created_at : Tue Jul 02 03:30:50 +0000 2013 id :
Jul_02|created_at : Tue Sep 03 05:08:44 +0000 2013 id :
The problem is subtle. String.match expects a regular expression for its parameter, and, if it doesn't see one it tries to turn the parameter into an expression:
Converts pattern to a Regexp (if it isn’t already one), then invokes its match method on str.
So:
created_at : Tue Jul 02 03:30:50 +0000 2013 id :
isn't a pattern going in, and it gets converted to one.
The problem is the +. In regular expressions, + means one-or-more of the preceding character or group or character set.
The correct way to specify a literal match between your stringcomp and your newly created pattern would be for the pattern to be:
created_at : Tue Jul 02 03:30:50 \+0000 2013 id :
Notice the \+. That means the + is now a literal value, not a length specifier.
For visual proof, check these two Rubular tests:
Without escaping: http://rubular.com/r/L6Fwrw1ftf
Escaped: http://rubular.com/r/SjGAYtzHuS
That all said, the simple fix is to not try to use match, and instead use a substring search:
times = [
'Jul_01|created_at : Tue Jul 02 03:30:50 +0000 2013 id :',
'Jul_02|created_at : Tue Sep 03 05:08:44 +0000 2013 id :'
]
stringcomp = "created_at : Tue Jul 02 03:30:50 +0000 2013 id : 351905778745094144 id_str : 351905778745094144"
times.each do |t|
timestamp = t.split('|').last
puts stringcomp[timestamp] || 'sub-string not found'
end
Which outputs:
created_at : Tue Jul 02 03:30:50 +0000 2013 id :
sub-string not found
If you want a boolean result, instead of the matching substring being returned you can use:
!!stringcomp[timestamp]
For example:
!!stringcomp['created_at : Tue Jul 02 03:30:50 +0000 2013 id :'] # => true
Alternately, you could use Regexp.escape on your string, prior to passing it in to match, but I think that's overkill when a substring match will accomplish what you want.
You could also...
stringcomp.include? timestamp

Resources