1

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?

4
  • 1
    Do you only want to split this specific string? For example, you could split it after X number of characters, but that won't really work if the version number gets any longer. Commented Oct 27, 2021 at 13:38
  • 1
    Try to work a bit of code, start by splitting the string. Commented Oct 27, 2021 at 13:38
  • I tried below code ``` $ILOData = Get-Content .\abc.txt $ILODevice= $ILOData |Where{Select-String -pattern "Device: "}``` got string as "Device: ILO 5 Firmware Version : 2:33 Firmware date : 10-10-2020" then tried to split this string $ILoDevice.Split() and ```$ILoDevice -Split " "```` but no luck Commented Oct 27, 2021 at 13:41
  • 1
    @PuneetTiwari edit the question and paste your code there, don't post that in comment Commented Oct 27, 2021 at 14:56

5 Answers 5

1

A generalized solution, which:

  • doesn't require knowing the field names in advance.
  • returns the field values only, as an array (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, 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
Sign up to request clarification or add additional context in comments.

Comments

0

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

1 Comment

any other way too to get this acheived?
0

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

2 Comments

perfect.. now I want to use Device, FWVersion and FWdate in below code ``` $data = ""$ILO_Name","$Model","$ILO_Domain","$Network_Details","$ILO_TimeZone","$($Directory_Users.trimend())","","$($DIR_GRPACCTS.trimend())"" $Data |Out-File -Append $ILOContent```
@PuneetTiwari Assuming you assign the resulting [pscustomobject] to a variable $object, it'd be $object.Device instead of $ILO_Name. Are you trying to construct a CSV file? If yes, you'd probably want to make use of Export-Csv instead of manually stitching the rows together
0

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

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.