Reputation: 41
I have a string as "Device: ILO 5 Firmware Version : 2:33 Firmware date : 10-10-2020"
I want to split this string as below in an array
ILO 5
2:33
10-10-2020
How can it be done in powershell?
Upvotes: 1
Views: 2872
Reputation: 8868
Here's another approach using regex that may be easier to read.
# store the string for the following demonstrations
$str = "Device: ILO 5 Firmware Version : 2:33 Firmware date : 10-10-2020"
$str -split '\s*:\s{1,}|\s(?!\d)'
This will give us the following array
Device
ILO 5
Firmware
Version
2:33
Firmware
date
10-10-2020
Now we just pick out the desired values
$device,$fwversion,$fwdate = ($str -split '\s*:\s{1,}|\s(?!\d)')[1,4,7]
[PSCustomObject]@{
Device = $device
FWVersion = $fwversion
FWDate = $fwdate
}
Output
Device FWVersion FWDate
------ --------- ------
ILO 5 2:33 10-10-2020
You could also use pass all the elements into a ForEach-Object
loop like this.
,($str -split '\s*:\s{1,}|\s(?!\d)') | ForEach-Object {
[PSCustomObject]@{
Device = $_[1]
FWVersion = $_[4]
FWDate = $_[7]
}
}
Note the comma that makes the output get passed through as part of an array.
The regex pattern splits on a colon that is followed by at least 1 space and has an optional space in front of it OR a space that is not followed by a numeric digit.
Upvotes: 0
Reputation: 437176
A generalized solution, which:
# Sample input string.
$str = 'Device: ILO 5 Firmware Version : 2:33 Firmware date : 10-10-2020'
# Split so as to only return field *values*.
$str -split '(?:^| +)\w+ ?\w* *: +' -ne ''
Assumptions:
': '
_
and at most one space (i.e. are composed of one or two words).Output:
ILO 5
2:33
10-10-2020
For an explanation of the above regex used with the -split
operator, including the ability to experiment with it, see this regex101.com page.
-ne ''
filters out the unwanted empty token that results from the regex also matching at the start of the input string.
To also capture the field names, and return an (ordered) hashtable or [pscustomobject]
, more work is needed:
# Sample input string.
$str = 'Device: ILO 5 Firmware Version : 2:33 Firmware date : 10-10-2020'
# Split into field names and values.
# Note the capture group - (...) - around the sub-expresssion
# that matches the field name.
# -split includes capture-group matches in the result.
$namesAndValues = $str -split '(?:^| +)(\w+ ?\w*) *: +' -ne ''
# Construct an ordered hashtable from the name-value pairs
# You can easily convert it to a [pscustomobject] with: [pscustomobject] $result
$result = [ordered] @{}
for ($i = 0; $i -lt $namesAndValues.Count; $i += 2) {
$result[$namesAndValues[$i]] = $namesAndValues[$i+1]
}
# Output the result:
$result
Output:
Name Value
---- -----
Device ILO 5
Firmware Version 2:33
Firmware date 10-10-2020
Upvotes: 1
Reputation: 27428
You can split the string on whitespace, but ILO and 5 will be two different array elements. The comma operator has a higher precedence than the join operator, hence the parentheses.
$string = 'Device: ILO 5 Firmware Version : 2:33 Firmware date : 10-10-2020'
$split = -split $string
($split[1,2] -join ' '),$split[6,10]
ILO 5
2:33
10-10-2020
Upvotes: 0
Reputation: 59
This might be ugly and there might be other ways but this is one way to do it:
First create an empty array:
$Array = @()
Get all the elements in a temp array:
$TempArray = "Device: ILO 5 Firmware Version : 2:33 Firmware date : 10-10-2020" -split(' ')
Next add the first values in the temparray, index 1 and 2, as a string:
$array += $temparray[1..2] -as [string]
Then add the others:
$Array += $temparray[6]
$Array += $temparray[-1]
This adds the sixth and the last element (-1). The result is:
ILO 5
2:33
10-10-2020
Upvotes: 0
Reputation: 174465
You could use a regular expression to match and extract the values:
$string = "Device: ILO 5 Firmware Version : 2:33 Firmware date : 10-10-2020"
if($string -match 'Device:\s*(.*?)\s*Firmware Version :\s*(.*?)\s*Firmware date :\s*([\d\-]+)'){
[pscustomobject]@{
Device = $Matches[1]
FWVersion = $Matches[2]
FWDate = $Matches[3]
}
}
\s*
matches 0 or more spaces, .*?
matches 0 or more of any characters, non-greedily, and [\d\-]+
will find any sequence of one or more characters that are either digits or -
. The ()
around .*?
and [\d\-]+
instructs the regex engine to capture the matching values, which is how we can then extract those values from the automatic $Matches
variable afterwards.
This should produce an object with those three properties:
Device FWVersion FWDate
------ --------- ------
ILO 5 2:33 10-10-2020
Upvotes: 0