I have a string in Powershell that is a javascript object. That is, it is a line of text stripped from a Javascript file, for instance, I might have
$theline = "{'prod_id':'123456789','prod_price':'100.00','prod_name':'Creative Software Package','prod_img':'https://mysite/images/123456789?$400x350$','prod_desc':'Software - Package - PC - Win7 - x64'};"
The Javascript elements might have values which contain more than just alphanumeric characters, and I don't think I can guarantee that they won't contain commas.
What I need to do is convert this variable into a Powershell Hash table.
First I was thinking about converting the string into a syntax that would match the ConvertFrom-StringData cmdlet. So the end result would be something like...
$convertedstr = #'
prod_id = 123456789
prod_price = 100.00
prod_name = Creative Software Package
prod_img = https://mysite/images/123456789?$400x350$
prod_desc = Software - Package - PC - Win7 - x64
'#
$table = ConvertFrom-StringData $convertedstr
$table
Name Value
---- -----
prod_desc Software - Package - PC - Win7 - x64
prod_name Creative Software Package
prod_id 123456789
prod_img https://mysite/images/123456789?$400x350$
prod_price 100.00
But I'm not sure how to go about the string replace to get that done. I also found the ConvertFrom-JSON cmdlet, but since I'm on Powershell 2.0 it isn't available to me.
I had tried something like
$theline = $theline -Replace "\{'(\w+)':'(.+)',?\};",'$1 = $2`n'
But it isn't matching it the way I'd like.
$theline
prod_name = Creative Software Package','prod_id':'123456789','prod_price':'100.00`n
I get why the regex is matching what it is, but I'm not sure how to get it to match each "element."
Any ideas for this? I'm open to something that might be easier than this string conversion and a regex replace as well.
Thanks in advance.
Trim the { from the start, and the }; from the end, and that basically leaves you with an array of Key:Value pairs. Then just create a PSCustomObject, and add members to it for each pair by splitting that array on the , and doing a RegEx match on each one.
$theline = "{'prod_id':'123456789','prod_price':'100.00','prod_name':'Creative Software Package','prod_img':'https://mysite/images/123456789?$400x350$','prod_desc':'Software - Package - PC - Win7 - x64'};"
$JavaImport = New-Object PSObject
$theline.TrimStart("{").trimend("};").split(",")|?{$_ -match "^'(.+?)':'(.+?)'$"}|%{Add-Member -InputObject $JavaImport -NotePropertyName ($Matches[1]) -NotePropertyValue ($Matches[2])}
PS C:\Users\TMTech> $JavaImport
prod_id : 123456789
prod_price : 100.00
prod_name : Creative Software Package
prod_img : https://mysite/images/123456789?$
prod_desc : Software - Package - PC - Win7 - x64
And I just realized you wanted a hashtable. My bad. Let my revise that a hair.
$theline = "{'prod_id':'123456789','prod_price':'100.00','prod_name':'Creative Software Package','prod_img':'https://mysite/images/123456789?$400x350$','prod_desc':'Software - Package - PC - Win7 - x64'};"
$JavaImport = #{}
$theline.TrimStart("{").trimend("};").split(",")|?{$_ -match "^'(.+?)':'(.+?)'$"}|%{$JavaImport.add($Matches[1],$Matches[2])}
PS C:\Users\TMTech> $JavaImport
Name Value
---- -----
prod_desc Software - Package - PC - Win7 - x64
prod_img https://mysite/images/123456789?$
prod_id 123456789
prod_price 100.00
prod_name Creative Software Package
This is already accepted, but I thought I'd comment on the origin line there. Because the OP was inputting it with double quotes we actually lost part of the URL. I ended up changing it to the following on my end:
$theline = '''prod_id'':''123456789'',''prod_price'':''100.00'',''prod_name'':''Creative Software Package'',''prod_img'':''https://mysite/images/123456789?$400x350$'',''prod_desc'':''Software - Package - PC - Win7 - x64'''
That way I could better match his desired input text. After that I stopped losing the $400x350 on the URL. Also, the RegEx escaping is a good idea, so the final solution for the user was:
$theline = '''prod_id'':''123456789'',''prod_price'':''100.00'',''prod_name'':''Creative Software Package'',''prod_img'':''https://mysite/images/123456789?$400x350$'',''prod_desc'':''Software - Package - PC - Win7 - x64'''
$JavaImport = #{}
[regex]::escape($theline).split(",")|?{$_ -match "^'(.+?)':'(.+?)'$"}|%{$JavaImport.add([regex]::unescape($Matches[1]),[regex]::unescape($Matches[2]))}
Related
I have Dell servers with iDrac 8. Monitoring: Prometheus+snmp_exporter+Grafana.
MIB: iDRAC-SMIv2
OID: 1.3.6.1.4.1.674.10892.5.4.300.40.1.8
From SNPP I get eventLogDateName in format: 20201222152131.000000+120
How can I use regex for replace 20201222152131.000000+120 to 12/22/20 15:21:31. I don't know where is I need insert my regex.
P.S.
pattern = '^(?P<YYYY>\d{4})(?P<MM>\d{2})(?P<DD>\d{2})(?P<HH>\d{2})(?P<mm>\d{2})(?P<ss>\d{2})\.(?P<SSSSSS>\d{6})(?P<ZZ>[-+]\d{3,4})$'
replacement = "${YYYY}-${MM}-${DD} ${HH}:${mm}:${ss}"
I am just learning bash scripting and commands and i need some help with this assignment.
I have txt file that contains the following text and i need to:
Extract guest name ( 1.1.1 ..)
Sum guest result and output the guest name with result.
I used sed with simple regex to extract out the name and the digits but i have no idea about how to summarize the numbers becuase the guest have multiple lines record as you can see in the txt file. Note: i can't use awk for processing
Here is my code:
cat file.txt | sed -E 's/.*([0-9]{1}.[0-9]{1}.[0-9]{1}).*([0-9]{1})/\1 \2/'
And result is:
1.1.1 4
2.2.2 2
1.1.1 1
3.3.3 1
2.2.2 1
Here is the .txt file:
Guest 1.1.1 have "4
Guest 2.2.2 have "2
Guest 1.1.1 have "1
Guest 3.3.3 have "1
Guest 2.2.2 have "1
and the output should be:
1.1.1 = 5
2.2.2 = 3
3.3.3 = 1
Thank you in advance
I know your teacher wont let you use awk but, since beyond this one exercise you're trying to learn how to write shell scripts, FYI here's how you'd really do this job in a shell script:
$ awk -F'[ "]' -v OFS=' = ' '{sum[$2]+=$NF} END{for (id in sum) print id, sum[id]}' file
3.3.3 = 1
2.2.2 = 3
1.1.1 = 5
and here's a bash builtins equivalent which may or may not be what you've covered in class and so may or may not be what your teacher is expecting:
$ cat tst.sh
#!/bin/env bash
declare -A sum
while read -r _ id _ cnt; do
(( sum[$id] += "${cnt#\"}" ))
done < "$1"
for id in "${!sum[#]}"; do
printf '%s = %d\n' "$id" "${sum[$id]}"
done
$ ./tst.sh file
1.1.1 = 5
2.2.2 = 3
3.3.3 = 1
See https://www.artificialworlds.net/blog/2012/10/17/bash-associative-array-examples/ for how I'm using the associative array. It'll be orders of magnitude slower than the awk script and I'm not 100% sure it's bullet-proof (since shell isn't designed to process text there are a LOT of caveats and pitfalls) but it'll work for the input you provided.
OK -- since this is a class assignment, I will tell you how I did it, and let you write the code.
First, I sorted the file. Then, I read the file one line at a time. If the name changed, I printed out the previous name and count, and set the count to be the value on that line. If the name did not change, I added the value to the count.
Second solution used an associative array to hold the counts, using the guest name as the index. Then you just add the new value to the count in the array element indexed on the guest name.
At the end, loop through the array, print out the indexes and values.
It's a lot shorter.
This question is related to RegEx find all XML tags but I'm trying to do it in Windows PowerShell.
I have an XML file that contains many different XML tags, and the file is Huge, so basically I want to use RegEx to parse the file and spit out the name of all the tags as a list. The XML document is not a valid XML document even though it contains XML tags and elements. So using the XML functions of PowerShell won't work. I get many errors when trying to view it as an XML document, thus the need to use RegEx.
I've determined that the following RegEx identifies the tags (thanks to the related question mentioned above): (?<=<)([^\/]*?)((?= \/>)|(?=>))
Here's a very small sniplet of the file I'm parsing:
<data><bp_year /><bp_make>John Deere</bp_make><bp_model>650</bp_model><bp_price>3000.00</bp_price><bp_txtDayPhone>555-555-5555</bp_txtDayPhone><bp_bestPrice>3000.0000</bp_bestPrice><bp_txtComments>Best price available?</bp_txtComments><bp_url>https://www.example.com</bp_url></data>
<data><receiveOffers /><link>http://example.com/inventory.htm?id=2217405&used=1</link><itemName>2007 Yamaha RHINO 660</itemName></data>
<data><vehicleYear>2008</vehicleYear><vehicleMake>Buick</vehicleMake><vehicleModel>Enclave</vehicleModel><vehicleStyle>CX</vehicleStyle><vehicleInformation /><vehicleMileage /><phone>555-555-5555</phone><timeOfDay>Morning</timeOfDay><message /></data>
<data><mo_year>2009</mo_year><mo_make>Webasto</mo_make><mo_model>Air Top 2000</mo_model><mo_price /><mo_txtDayPhone>555-555-5555</mo_txtDayPhone><mo_txtOffer>700</mo_txtOffer><mo_txtTrade /><mo_txtComments /></data>
I really don't have much experience with Powershell, but from my understanding, you can do Grep stuff with it. After searching around on the internet, I found some resources that helped point me towards my solution, via using the powershell Select-String command.
I've attempted the following powershell command, but it gives me way too much feedback. I just want a master "Matches" list.
Select-String -Path '.\dataXML stuff - Copy.xml'-Pattern "(?<=<)([^\/]*?)((?= \/>)|(?=>))" -AllMatches | Format-List -Property Matches
Sample of Output generated:
Matches : {data, vehicleYear, vehicleMake, vehicleModel...}
Matches : {data, address, city, region...}
Matches : {data, vehicleYear, vehicleMake, vehicleModel...}
Matches : {data, vehicleYear, vehicleMake, vehicleModel...}
Matches : {data, address, city, region...}
Matches : {data, vehicleYear, vehicleMake, vehicleModel...}
Matches : {data, vehicleYear, vehicleMake, vehicleModel...}
Matches : {data, mo_year, mo_make, mo_model...}
Basically, I want something like:
data
vehicleYear
vehicleMake
vehicleModel
address
city
region
mo_year
mo_make
mo_model
and so on and on....
Where only the matched strings are returned and listed, rather than telling me what matched on each line of the XML file. I prefer the list format because then I can pump this into Excel and get a distinct list of tag names, and then start actually doing what I need to accomplish, but the overwhelming number of different XML tags and not knowing what they are is holding me up.
Maybe Select-String isn't the best method to use, but I feel like I'm close to my solution after finding this Microsoft post:
https://social.technet.microsoft.com/Forums/windowsserver/en-US/d5bbd2fb-c8fa-43ed-b432-79ebfeee82ea/return-only-matches-from-selectstring?forum=winserverpowershell
Basically, here's the solution modified to fit my needs:
Gc 'C:\Documents\dataXML stuff - Copy.xml'|Select-String -Pattern "(?<=<)([^\/]*?)((?= \/>)|(?=>))"|foreach {$_.matches}|select value
It provides a list of all the xml tags, just like I wanted, except it only returns the first XML tag of that line, so I get a lot of:
data
data
data
but no vehicleYear, vehicleMake, vehicleModel, etc., which would have been the 2nd or 3rd or 11th xml tag of that line.
As for ...
Like I mentioned earlier in the post, I do not use PowerShell at all
Reading is a good thing, but see it in action is better. There are many free video resources to view PowerShell from the beginning, and tons of references. Then the are the MS TechNet virtual labs to leverage.
See this post for folks providing some paths for learning PowerShell.
Does anyone have any experience teaching others powershell?
https://www.reddit.com/r/PowerShell/comments/7oir35/help_with_teaching_others_powershell
Sure you could do it with RegEx, but it is best to handle it natively.
In PowerShell, XML is a big deal; as is JSON. All the help files a just XML files. There are bulit-in cmdlets to deal with it.
# Get parameters, examples, full and Online help for a cmdlet or function
Get-Command -Name '*xml*' | Format-Table -AutoSize
(Get-Command -Name Select-Xml).Parameters
Get-help -Name Select-Xml -Examples
Get-help -Name Select-Xml -Full
Get-help -Name Select-Xml -Online
Get-Help about_*
# Find all cmdlets / functions with a target parameter
Get-Help * -Parameter xml
# All Help topics locations
explorer "$pshome\$($Host.CurrentCulture.Name)"
And many sites that present articles on dealing with it.
PowerShell Data Basics: XML
To master PowerShell, you must know how to use XML. XML is an essential data interchange format because it remains the most reliable way of ensuring that an object's data is preserved. Fortunately, PowerShell makes it all easy, as Michael Sorens demonstrates.
https://www.red-gate.com/simple-talk/sysadmin/powershell/powershell-data-basics-xml
Converting XML to PowerShell PSObject
Recently, I was working on some code (of course) and had a need to convert some XML to PowerShell PSObjects. I found some snippets out there that sort of did this, but not the way that I needed for this exercise. In this case I’m converting XML meta data from Plex.
https://consciouscipher.wordpress.com/2015/06/05/converting-xml-to-powershell-psobject
Mastering everyday XML tasks in PowerShell
PowerShell has awesome XML support. It is not obvious at first, but with a little help from your friends here at PowerShellMagazine.com, you’ll soon solve every-day XML tasks – even pretty complex ones – in no time.
So let’s check out how you put very simple PowerShell code to work to get the things done that used to be so mind-blowingly complex in the pre-PowerShell era.
http://www.powershellmagazine.com/2013/08/19/mastering-everyday-xml-tasks-in-powershell
For all intents and purposes, if I just take one row for your sample, and do this using the .Net xml namespace...
($MyXmlData = [xml]'<data><bp_year /><bp_make>John Deere</bp_make><bp_model>650</bp_model><bp_price>3000.00</bp_price><bp_txtDayPhone>555-555-5555</bp_txtDayPhone><bp_bestPrice>3000.0000</bp_bestPrice><bp_txtComments>Best price available?</bp_txtComments><bp_url>https://www.example.com</bp_url></data>')
data
----
data
You get resutls like this...
$MyXmlData.data
bp_year :
bp_make : John Deere
bp_model : 650
bp_price : 3000.00
bp_txtDayPhone : 555-555-5555
bp_bestPrice : 3000.0000
bp_txtComments : Best price available?
bp_url : https://www.example.com
with intellisene / autocomplete of the nodes / elements...
$MyXmlData.data.bp_year
Another view...
$MyXmlData.data | Format-Table -AutoSize
bp_year bp_make bp_model bp_price bp_txtDayPhone bp_bestPrice bp_txtComments bp_url
------- ------- -------- -------- -------------- ------------ -------------- ------
John Deere 650 3000.00 555-555-5555 3000.0000 Best price available? https://www.example.com
And from that, just geting the tags / names
$MyXmlData.data.ChildNodes.Name
bp_year
bp_make
bp_model
bp_price
bp_txtDayPhone
bp_bestPrice
bp_txtComments
bp_url
So, armed with the above approaches / notes. It just becomes a matter of looping through your file to get all you are after.
So, just taking your sample and dumping it into a file with no changes, one can do this.
$MyXmlData = (Get-Content -Path 'D:\Scripts\MyXmlData.xml')
$MyXmlData | Format-List -Force
ForEach($DataRow in $MyXmlData)
{
($DataObject = [xml]$DataRow).Data | Format-Table -AutoSize
}
bp_year bp_make bp_model bp_price bp_txtDayPhone bp_bestPrice bp_txtComments bp_url
------- ------- -------- -------- -------------- ------------ -------------- ------
John Deere 650 3000.00 555-555-5555 3000.0000 Best price available? https://www.example.com
receiveOffers link itemName
------------- ---- --------
http://example.com/inventory.htm?id=2217405&used=1 2007 Yamaha RHINO 660
vehicleYear vehicleMake vehicleModel vehicleStyle vehicleInformation vehicleMileage phone timeOfDay message
----------- ----------- ------------ ------------ ------------------ -------------- ----- --------- -------
2008 Buick Enclave CX 555-555-5555 Morning
mo_year mo_make mo_model mo_price mo_txtDayPhone mo_txtOffer mo_txtTrade mo_txtComments
------- ------- -------- -------- -------------- ----------- ----------- --------------
2009 Webasto Air Top 2000 555-555-5555 700
ForEach($DataRow in $MyXmlData)
{
($DataObject = [xml]$DataRow).Data.ChildNodes.Name
}
bp_year
bp_make
bp_model
bp_price
bp_txtDayPhone
bp_bestPrice
bp_txtComments
bp_url
receiveOffers
link
itemName
vehicleYear
vehicleMake
vehicleModel
vehicleStyle
vehicleInformation
vehicleMileage
phone
timeOfDay
message
mo_year
mo_make
mo_model
mo_price
mo_txtDayPhone
mo_txtOffer
mo_txtTrade
mo_txtComments
Yet, note, this is not the only way to do this.
I have text as:
[img]http://cimislia.net/uploads/posts/2013-07/1373995142_vrc.png[/img]
[color=#3333FF]Дата выхода: 26 октября 2012
Жанр: Racing, Simulator, 3D
Разработчик: SCS Software
Издательство: Excalibur Publishing
I want to remove everything after [/img] so above text will be:
[img]http://cimislia.net/uploads/posts/2013-07/1373995142_vrc.png[/img]
Can somebody help please? How to do this with regex?
This regex
\[img\].*\[/img\]
will match only [img] tags and everything between.
How to use it depends on the programming language you are using.
Example in C#:
var text = #"[img]http://cimislia.net/uploads/posts/2013-07/1373995142_vrc.png[/img]
[color=#3333FF]Дата выхода: 26 октября 2012
Жанр: Racing, Simulator, 3D
Разработчик: SCS Software
Издательство: Excalibur Publishing
";
Regex regex = new Regex("\\[img\\].*\\[/img\\]");
var imgOnly = regex.Match(text).Value;
you can search for \[/img\](.|\n)* and replace with [/img]
Looking at the xml file created by HitManPro I can see numerous entries like this one;
[Item type="Malware" malwareName="Trojan" score="0.0" status="None"]
This are the false positives.
I would like to replace the existing RegEX query that I use in a script (LabTech) with one that would look for anything like;
score="5.1" up to score="999.0"
I am new to Reg Ex queries, and I am having trouble building the search for digits inside the string score=" " .
Any help would be much appreciated. Below is a sample XML from hitmanPro
regards,
Oscar Romero
<br>
HitmanPro Scan Completed Successfully.
Threats Found!
<hr>
Scan Date: 2015-10-17T15:16:31<BR>
<p>"
[Log computer="computer name" windows="6.1.1.7601.X64/12" scan="Normal" version="3.7.9.246" date="2015-10-17T15:16:31" timeSpentInSecs="125" filesProcessed="15922"]
[Item type="Malware" malwareName="Malware" score="90.0" status="None"]
[Scanners]
[Scanner id="Bitdefender" name="Gen:Variant.Kazy.751212" /]
[/Scanners]
[File path="C:\Program Files (x86)\ESET\ESET Remote Administrator\Server\era.exe" hash="F7BB46D48B994539AFD400641CE8E4F85114FC7BA05A1BAA0D092F3A92817F13" /]
[Startup]
[Key path="HKLM\SYSTEM\CurrentControlSet\Services\ERA_SERVER\" /]
[/Startup]
[/Item]
[/Log]
"</p>
There must be a shorter version than this, but this should work.
score="(0\.[1-9]|[1-9]\.[0-9]|[1-9][0-9]\.[0-9]|[1-9][0-9][0-9]\.[0-9])"
Matches:
0.1
1.0
10.4
100.9
100.0
999.9
99.9
9.9
(etc.)
Does Not Match
0.0
0
(etc.)
Is regex the way to go?
As for whether regex is the right tool for the job, I probably agree with #Makoto that it isn't - unless you're doing a quick scan of the results as an FYI, rather than filtering results as part of a larger tool or application. In other words, except for the simplest cases, I agree with #Makoto that you want some xml parsing tool.
I have no idea on LabTech.
Anyway, the regex query that you can use:
\sscore="((?:5\.[1-9])|(?:[6-9]\.[0-9])|(?:[1-9]{1}[0-9]{1,2}\.[0-9]))"\s
or
\sscore="(5\.[1-9]|[6-9]\.[0-9]|[1-9]{1}[0-9]{1,2}\.[0-9])"\s
if you prefer without the (?: ... )
UPDATE:
Okay, I made further changes to support the 5.1 minimum, and max 999.9
PS: This is my first answer on StackOverflow