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?
CodePudding user response:
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
CodePudding user response:
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
CodePudding user response:
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
CodePudding user response:
A generalized solution, which:
- doesn't require knowing the field names in advance.
- returns the field values only (as stipulated in your question - see bottom section if want to capture name-value pairs):
# 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:
- No value contains substring
': '
- Names contain only letters and
_
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, 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