Split text file contents with Regular Expressions for delimiters? - regex

I have a text file containing the results of a zone transfer & need to read each line & split it into an array to output a list of server names & IP addresses. However I'me having some problems splitting the data as my attempt at the whitespace delimiter doesn't seem to be doing what I want it to.
Sample input:
machine1.fqdn.com. 86400 IN A 192.168.1.10
machine2.fqdn.com. 86400 IN A 192.168.1.11
machine3.fqdn.com. 86400 IN A 192.168.1.12
machine4.fqdn.com. 86400 IN A 192.168.1.13
Script:
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("I:\testHarvestIF.txt", ForReading)
Const ForReading = 1
Do Until objFile.AtEndOfStream
strNextLine = objFile.Readline
arrServiceList = Split(strNextLine," ",-1,1)
Wscript.Echo "Server name: " & arrServiceList(0) & vbCrLF & _
" - IP Address: " & arrServiceList(2)
Loop
objFile.Close
Current Output:
Server name: machine1.fqdn.com.
IP Address: IN A 192.168.1.10
Server name: machine2.fqdn.com.
IP Address: IN A 192.168.1.11
Server name: machine3.fqdn.com.
IP Address: IN A 192.168.1.12
Server name: machine4.fqdn.com.
IP Address: IN A 192.168.1.13
Desired output:
Server name: machine1.fqdn.com.
IP Address: 192.168.1.10
Server name: machine2.fqdn.com.
IP Address: 192.168.1.11
Server name: machine3.fqdn.com.
IP Address: 192.168.1.12
Server name: machine4.fqdn.com.
IP Address: 192.168.1.13
Is there some way I could use a regular expresion to use any length of whitespace as a delimiter? E.g.
arrServiceList = Split(strNextLine,"^\s+",-1,1)
Thanks in advance for any assistance you can offer.
Regards,
RB

This might not work, depending on the format of your data, but you could try replacing the extra whitespace with a single space character before calling Split:
Dim re : Set re = New RegExp
re.Global = True
re.Pattern = "\s+"
Do Until objFile.AtEndOfStream
strNextLine = re.Replace(objFile.Readline, " ")
arrServiceList = Split(strNextLine," ",-1,1)
Wscript.Echo "Server name: " & arrServiceList(0) & vbCrLF & _
" - IP Address: " & arrServiceList(4)
Loop

Use the RegExp object (MSDN) to match the required string instead of spliting the string:
set regex = new RegExp
regexp.pattern = "^.*? "
set serverName = regex.execute(inputText).value
regex.pattern = " .*?$"
set ipAddress = regex.execute(inputText).value

Related

Ansible replace a value in big config file

I have a config file with more than 3000 lines, where i need to change/replace only few parameters.
since the config file is huge. am unable to use the template.
Need help in replacing the below parameters.
gateway-config {
enable = true
host-name = "car-cache"
port = 202
batch-size = 100
patterns = ["^((test))"]
type = LINE
prefix = "stats."${auth}".service"
}
k9-config {
enable = true
send-enable = false
host-name = ${auth}
connection-timeout = 120000
read-timeout = 60000
proxy = ""
project = "Networking"
period = 120
I need to replace the enable = false to enable = true only on some-config but when i use replace module the whole enable = false is replaced in the config file.
You can actually use the replace module with the after and before parameters:
- name: Replace between the expressions (requires Ansible >= 2.4)
replace:
path: /path/to/your/file
after: 'gateway-config {'
before: '}'
regexp: '^(\s*enable = )false$'
replace: '\g<1>true'
can you use replace module:
---
- name: Replace variable
replace:
path: "/etc/repli.conf"
after: "hite-config {"
regexp: "enable = false"
replace: "enable = true"

Problem with chilkat ActiveX HTTP component with Redirect

I used this script to check the last redirect url:
set http = CreateObject("Chilkat_9_5_0.Http")
http.FollowRedirects = 0
' resp is a Chilkat_9_5_0.HttpResponse
Set resp = http.QuickGetObj(link)
If (http.LastMethodSuccess = 0) Then
wscript.echo http.LastErrorText
WScript.Quit
End If
status = resp.StatusCode
wscript.echo "HTTP Response Status: " & status
wscript.echo "Redirect URL >>>: " & http.FinalRedirectUrl
nextUrl = http.WasRedirected
loopCount = 0
Do While (status = 302 OR status = 301)
wscript.echo "HTTP Response Status: " & status
wscript.echo "Redirect URL >>>: " & http.FinalRedirectUrl
nextUrl = http.FinalRedirectUrl
' resp is a Chilkat_9_5_0.HttpResponse
Set resp = http.QuickGetObj(nextUrl)
If (http.LastMethodSuccess = 0) Then
wscript.echo http.LastErrorText
WScript.Quit
End If
status = resp.StatusCode
wscript.echo "HTTP Response Status: " & status
' For safety, prevent infinite loops by
' keeping a loopCount and only allows following a max
' of 10 redirects:
loopCount = loopCount + 1
If (loopCount > 10) Then
wscript.echo "Too many redirects."
WScript.Quit
End If
Loop
This code prints the 301 status code correctly, but it doesn't print the http.FinalRedirectURL (it's blank).
I also tried with the url https://www.businessonline.it/articoli/guida-al-nuovo-regime-forfettario-2016-e-2017.html
The output is:
Link: https://www.businessonline.it/articoli/guida-al-nuovo-regime-forfettario-2016-e-2017.html
HTTP Response Status: 301
Redirect URL >>>:
HTTP Response Status: 301
Redirect URL >>>:
ChilkatLog:
QuickGetObj:
DllDate: Oct 28 2019
ChilkatVersion: 9.5.0.80
UnlockPrefix: BRKEVN.XXXXXXXXXXX
Architecture: Little Endian; 32-bit
Language: ActiveX
VerboseLogging: 0
Component successfully unlocked using purchased unlock code.
url:
verb: GET
quickRequestDb:
url:
getHttpConnectionByUrl:
urlObject_loadUrl:
No domain in URL
url:
--urlObject_loadUrl
--getHttpConnectionByUrl
--quickRequestDb
Failed.
--QuickGetObj
--ChilkatLog
I used both chilkat 9.5.0.70 and 9.5.0.80.
If I set FollowRedirects to 1, the first StatusCode is "200" and I can't get the url.
Can you help me?
Thank's
Thanks Lorenzo,
The problem had to do with QuickGetObj and QuickGet. The QuickGetStr method worked fine for the WasRedirected and FinalRedirectUrl properties.
Here's a new 32-bit ActiveX build with the fix:
32-bit: https://chilkatdownload.com/prerelease/chilkatax-9.5.0-win32-1630.zip

indexing output of linux command in c++

I want to get the ip address given url.
I am currently using this
std::string i;
std::string pingStr = (std::string)"nslookup " +"www.yahoo.com" ;
i = system (pingStr.c_str());
but the output is
Server: 127.0.1.1
Address: 127.0.1.1#53
Non-authoritative answer:
www.yahoo.com canonical name = atsv2-fp-shed.wg1.b.yahoo.com.
Name: atsv2-fp-shed.wg1.b.yahoo.com
Address: 106.10.250.10
Q: Is there anyway I can only get the Ip address?
Use the getaddrinfo(3) function to look up IP addresses, IPv4 or IPv6, in usable form.
you can use the folowing command.
nslookup www.yahoo.com | grep Address: | sed -n 2p
grep Address gives you all lines having "address" word in them
sed gets the 2nd line of those 2
You can truncate the "Address" part of output in c++.

How to get the specific content from the log file described bellow?

I Have a log file which is generated by nmap, which is something like this:
Nmap scan report for gateway (10.0.0.1)
Host is up (0.0060s latency).
MAC Address: 10:BE:F5:FC:9C:65 (D-Link International)
Nmap scan report for 10.0.0.2
Host is up (0.055s latency).
MAC Address: 7C:78:7E:E8:1C:2A (Samsung Electronics)
Nmap scan report for 10.0.0.3
Host is up (0.059s latency).
MAC Address: 54:60:09:83:6E:B6 (Google)
Nmap scan report for 10.0.0.200
Host is up (-0.093s latency).
MAC Address: 5C:B9:01:02:5F:D8 (Hewlett Packard)
Nmap scan report for manoj-notebook (10.0.0.4)
Host is up.
Nmap done: 256 IP addresses (5 hosts up) scanned in 16.84 seconds
It keeps on changing as the new devices connect to the network or existing device disconnects from the network. I want to fetch the ip address example: 10.0.0.1, mac address example: 10:BE:F5:FC:9C:65 and the device name example: D-Link International in a single list something like:
result = [['10.0.0.1', '10.0.0.2', '10.0.0.3', '10.0.0.200', '10.0.0.4'], ['10:BE:F5:FC:9C:65', '7C:78:7E:E8:1C:2A', '54:60:09:83:6E:B6', '5C:B9:01:02:5F:D8'], ['D-Link International', 'Samsung Electronics', 'Google', 'Hewlett Packard']]
I tried the following regular expression to match IP address, MAC Address and Device name:
ipPattern = re.findall(r'\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b', temp)
macPattern = re.findall(r'(?:.*?s: ){2}(.*)(?= \))', temp)
devicePattern = re.findall(r'(?:.*?\(){2}(.*)(?=\))', temp)
I'm able to match the IP Address but unable to match mac address and device name. How to match the same and store it in a single list? Thank you.
Also if I could get a pattern to fetch latency from the log file example: 0.0060s it would be a cherry on top. Thank you.
You can use the following expressions:
ipPattern : \b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b
macPattern : (?:[0-9A-F]{2}:){2,}[0-9A-F]{2}\b
(?:[0-9A-F]{2}:)+ Non capturing group for sequence of pairs of alphanumerical values followed by :.
[0-9A-F]+\b Final pair of alphanumerical value, followed by word boundary.
devicePattern : (?<=\()[^)0-9.]*(?=\))
(?<=\() Negative lookbehind for bracket ).
[^)0-9.]* Negated character set, matches anything that is not a ) or . or digits.
(?=\)) Positive lookahead for ).
latency : -?\d+\.\d+s(?=\slatency)
-?\d+\.\d+s Match - optionally, digits, full stop, more digits and s.
(?=\slatency) Positive lookahead, assert that what follows whitespace and latency.
Python snippet:
import re
import itertools
temp = """
b'\nStarting Nmap 7.60 ( https://nmap.org ) at 2018-08-03 19:44 IST\nNmap scan report for gateway (10.0.0.1)\nHost is up (0.0070s latency).\nMAC Address: 10:BE:F5:FC:9C:65 (D-Link International)\nNmap scan report for 10.0.0.3\nHost is up (0.11s latency).\nMAC Address: 54:60:09:83:6E:B6 (Google)\nNmap scan report for 10.0.0.5\nHost is up (0.11s latency).\nMAC Address: 7C:78:7E:A4:73:8C (Samsung Electronics)\nNmap scan report for 10.0.0.200\nHost is up (0.027s latency).\nMAC Address: 5C:B9:01:02:5F:D8
"""
ipPattern = re.findall(r'\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b', temp)
macPattern= re.findall(r'(?:[0-9A-F]{2}:){2,}[0-9A-F]{2}\b',temp)
devicePattern = re.findall(r'(?<=\()[^)0-9.]*(?=\))',temp)
latency = re.findall(r'-?\d+\.\d+s(?=\slatency)',temp)
print(ipPattern)
print(macPattern)
print(devicePattern)
print(latency)
Prints:
['10.0.0.1', '10.0.0.3', '10.0.0.5', '10.0.0.200']
['10:BE:F5:FC:9C:65', '54:60:09:83:6E:B6', '7C:78:7E:A4:73:8C', '5C:B9:01:02:5F:D8']
['D-Link International', 'Google', 'Samsung Electronics']
['0.0070s', '0.11s', '0.11s', '0.027s']
For joining in a single list use:
mylist = itertools.chain([ipPattern], [macPattern], [devicePattern], [latency])
print(list(mylist))
Prints:
[['10.0.0.1', '10.0.0.3', '10.0.0.5', '10.0.0.200'], ['10:BE:F5:FC:9C:65', '54:60:09:83:6E:B6', '7C:78:7E:A4:73:8C', '5C:B9:01:02:5F:D8'], ['D-Link International', 'Google', 'Samsung Electronics'], ['0.0070s', '0.11s', '0.11s', '0.027s']]

Windows Script to Parse names of WebSphere JVMs from a command output

I am writing a (batch file or VBScript) to nicely shutdown all the running WebSphere JVMs on a Windows server, but need help with some text handling. I want the script to run and parse the output of the "serverstatus" command to get the names of Application Servers on the box and store the matches (with carriage returns) in a variable for use in the rest of the script.
Sample command output:
C:\WebSphere\AppServer\bin>serverstatus -all
ADMU0116I: Tool information is being logged in file
C:\WebSphere\AppServer\profiles\MySrv01\logs\serverStatus.log
ADMU0128I: Starting tool with the MySrv01 profile
ADMU0503I: Retrieving server status for all servers
ADMU0505I: Servers found in configuration:
ADMU0506I: Server name: MyCluster_MySrv01
ADMU0506I: Server name: MyCluster_MySrv01_1
ADMU0506I: Server name: MyNextCluster_MySrv04
ADMU0506I: Server name: MyNextCluster_MySrv04_1
ADMU0506I: Server name: nodeagent
ADMU0508I: The Application Server "MyCluster_MySrv01" is STARTED
ADMU0508I: The Application Server "MyCluster_MySrv01_1" is STARTED
ADMU0508I: The Application Server "MyNextCluster_MySrv04" is STARTED
ADMU0509I: The Application Server "MyNextCluster_MySrv04_1" cannot be
reached. It appears to be stopped.
ADMU0508I: The Node Agent "nodeagent" is STARTED
*nodeagent should NOT match. The jury is still out on whether I want to target all app servers or just those with a status of "STARTED".
Here's an alternative to using Regex. It simply reads stdout and processes all started app servers - the app servers are stored in an array called AppServers. Tested on W2K3.
Edit: We have added a way to log output to a file by adding a log write function (don't forget to add the const ForAppending at the start of the script that we have just added to this answer). The log write function takes the format of:
Logwrite "some text to write - delete file if exists", "c:\Path\filename.txt", 1
Logwrite "some text to write - append to file, don't delete", "c:\path\filename.txt", 0
It is a crude function, but does what you ask. I hope that helps. :)
option explicit
Const ForAppending = 8
Dim objShell, objWshScriptExec, objStdOut
Dim objCmdString, strLine, appServers(), maxAppServers
Dim x
' File Path / Location to serverstatus.bat ----
objCmdString = "C:\WebSphere\AppServer\bin\serverstatus.bat -all"
Set objShell = CreateObject("WScript.Shell")
Set objWshScriptExec = objShell.Exec(objCmdString)
Set objStdOut = objWshScriptExec.StdOut
MaxAppServers = -1
' While we're looping through the response from the serverstatus command, look for started application servers
' and store them in an ever expanding array AppServers.
' The Variable MaxAppServers should always contain the highest number of AppServers (ie: ubound(AppServers))
While Not objStdOut.AtEndOfStream
strLine = objStdOut.ReadLine
If InStr(LCase(strLine), "admu0508i: the application server """) Then
MaxAppServers = MaxAppServers + 1
ReDim Preserve AppServers(MaxAppServers)
AppServers(MaxAppServers) = wedge(strLine, Chr(34))
End If
Wend
If MaxAppServers => 0 then
For x = 0 To ubound(AppServers) ' You could just use For x = 1 to MaxAppServers in this case.
' Add your instructions here.........
' ... We are simply echoing out the AppServer name below as an example to a log file as requested below.
Logwrite AppServers(x), "c:\Output.log", 0
Next
End If
Function Wedge(wStr, wOpr)
' This clunky function simply grabs a section of a string the is encapsulated by wOpr.
' NOTE: This function expects wOpr to be a single character (eg; for our purpose, it is pulling data between double quotes).
Dim wFlag, wCount, wFinish
wflag = False
wFinish = False
wCount = 1
Wedge = ""
Do Until wCount > Len(wStr) Or wFinish
If Mid(wStr, wCount, 1) = wOpr Then
If wFlag Then
wFinish = True
Else
wFlag = True
End If
Else
If wFlag Then Wedge = Wedge & Mid(wStr, wCount, 1)
End If
wCount = wCount + 1
Loop
End Function
Function logwrite (lstrtxt, lwLogfile, lwflag)
Dim lwObjFSO, lwObjFile, fstr, lwcounter, lwc
fstr = lstrtxt
Set lwObjFSO = CreateObject("Scripting.FileSystemObject")
If lwflag=1 And lwObjFSO.FileExists(lwLogFile) Then lwObjfso.deletefile(lwLogFile)
If lwObjFSO.FileExists(lwLogFile) then
On Error Resume next
Set lwObjFile = lwObjFSO.OpenTextFile(lwLOgFile, ForAppending)
lwCounter = 20000
Do While Err.number = 70 And lwCounter > 0
wscript.echo "ERROR: Retrying output - Permission denied; File may be in use!"
For lwc = 1 To 1000000
Next
Err.clear
Set lwObjFile = lwObjFSO.OpenTextFile(lwLogFile, ForAppending)
lwCounter = lwCounter-1
Loop
If Err.number <> 0 Then
wscript.echo "Error Number: "&Err.number
wscript.quit
End If
On Error goto 0
Else
Set lwObjFile = lwObjFSO.CreateTextFile(lwLogFile)
End If
wscript.echo (fstr)
lwObjFile.Write (fstr) & vbcrlf
lwObjFile.Close
Set lwObjFSO=Nothing
Set lwObjfile=Nothing
End Function
Use a RegExp that cuts quoted names from your input; add context - Server, Started - to fine tune the result set. In code:
Option Explicit
Function q(s) : q = "'" & s & "'" : End Function
Dim sInp : sInp = Join(Array( _
"ADMU0116I: Tool information is being logged in file C:\WebSphere\AppServer\profiles\MySrv01\logs\serverStatus.log" _
, "ADMU0128I: Starting tool with the MySrv01 profile" _
, "ADMU0503I: Retrieving server status for all servers" _
, "ADMU0505I: Servers found in configuration:" _
, "ADMU0506I: Server name: MyCluster_MySrv01" _
, "ADMU0506I: Server name: MyCluster_MySrv01_1" _
, "ADMU0506I: Server name: MyNextCluster_MySrv04" _
, "ADMU0506I: Server name: MyNextCluster_MySrv04_1" _
, "ADMU0506I: Server name: nodeagent" _
, "ADMU0508I: The Application Server ""MyCluster_MySrv01"" is STARTED" _
, "ADMU0508I: The Application Server ""MyCluster_MySrv01_1"" is STARTED" _
, "ADMU0508I: The Application Server ""MyNextCluster_MySrv04"" is STARTED" _
, "ADMU0509I: The Application Server ""MyNextCluster_MySrv04_1"" cannot be reached. It appears to be stopped." _
, "ADMU0508I: The Node Agent ""nodeagent"" is STARTED" _
), vbCrLf)
Dim aRes : aRes = Array( _
Array("all quoted names", """([^""]+)""") _
, Array("all quoted started servers", "Server ""([^""]+)"" is STARTED") _
)
Dim aRE
For Each aRe In aRes
WScript.Echo "----------------", q(aRe(0)), q(aRe(1))
Dim re : Set re = New RegExp
re.Global = True
re.Pattern = aRe(1)
Dim oMTS : Set oMTS = re.Execute(sInp)
ReDim a(oMTS.Count - 1)
Dim i
For i = 0 To UBound(a)
a(i) = q(oMTS(i).SubMatches(0))
Next
WScript.Echo " =>", Join(a)
Next
output:
cscript 20984738.vbs
---------------- 'all quoted names' '"([^"]+)"'
=> 'MyCluster_MySrv01' 'MyCluster_MySrv01_1' 'MyNextCluster_MySrv04' 'MyNextCluster_MySrv04_1' 'nodeagent'
---------------- 'all quoted started servers' 'Server "([^"]+)" is STARTED'
=> 'MyCluster_MySrv01' 'MyCluster_MySrv01_1' 'MyNextCluster_MySrv04'