I have this string in a Powershell Variable:
$buildParametersSourceBranch = refs/heads/pb/31333-test-branch/name
When I run $buildParametersSourceBranch.split('/')[2]
The result is pb. I assumed the split would show everything after the second / but it seems to only show the value between the second / and third /.
String.Split() doesn't "know" that you're only interested in a particular subset of the result and only want the string split in 2 places.
Use the -split operator and specify a max number of resulting substrings:
$rest = ($buildParametersSourceBranch -split '/',3)[2]
# or
$null,$null,$rest = $buildParametersSourceBranch -split '/',3
Related
I am working on a code where I need to get the device id from below string
key-vim.host.PlugStoreTopology.Device-0200eb00006000097000029790063053303032344353594d4d4554
device id in this is 60000970000297900630533030323443
Now I wrote the below code where I am getting the index of 6000 and the taking the next 32 chars from there
$strPhrase = $plugs.Device
[int]$check_index = $strPhrase.IndexOf("6000")
$device = "naa."+$strPhrase.Substring($check_index,32)
Most of the cases the index value is 48, so I am able to fetch the proper data. but in few cases(e.g. key-vim.host.PlugStoreTopology.Device-0200e600006000097000029790063053303031343253594d4d4554) the index value is not same, so I am not getting the correct ID.
Please let me know how to get these values
If the string always looks like this (with Device- and then random 10 characters before the actual device id comes), you could do it using the following regex:
$deviceString = 'key-vim.host.PlugStoreTopology.Device-0200eb00006000097000029790063053303032344353594d4d4554'
$deviceString -replace '.*Device-.{10}(.{32}).*', '$1'
You can also get the value going from right to left if the value you're looking for is always the 32 characters long and 12 characters away from the right:
$str = 'key-vim.host.PlugStoreTopology.Device-0200eb00006000097000029790063053303032344353594d4d4554'
$str -replace '^.+(.{32}).{12}$', '$1'
yields 60000970000297900630533030323443
$str = 'key-vim.host.PlugStoreTopology.Device-0200e600006000097000029790063053303031343253594d4d4554'
$str -replace '^.+(.{32}).{12}$', '$1'
yields 60000970000297900630533030313432
or use the string .Substring() method
$str = 'key-vim.host.PlugStoreTopology.Device-0200eb00006000097000029790063053303032344353594d4d4554'
$str.Substring($str.Length - 44).Substring(0,32)
yields 60000970000297900630533030323443
I am using this to find if file name contains exactly 7 digits
if ($file.Name -match '\D(\d{7})(?:\D|$)') {
$result = $matches[1]
}
The problem is when there is a file name that contains 2 groups of 7 digits
for an example:
patch-8.6.22 (1329214-1396826-Increase timeout.zip
In this case the result will be the first one (1329214).
For most cases there is only one number so the regex is working but I must to recognize if there is more than 1 group and integrated into the if ()
The -match operator only ever looks for one match.
To get multiple ones, you must currently use the underlying .NET APIs directly, specifically [regex]::Matches():
Note: There's a green-lighted proposal to implement a -matchall operator, but as of PowerShell 7.3.0 it hasn't been implemented yet - see GitHub issue #7867.
# Sample input.
$file = [pscustomobject] #{ Name = 'patch-8.6.22 (1329214-1396826-Increase timeout.zip' }
# Note:
# * If *nothing* matches, $result will contain $null
# * If *one* substring matches, return will be a single string.
# * If *two or more* substrings match, return will be an *array* of strings.
$result = ([regex]::Matches($file.Name, '(?<=\D)\d{7}(?=\D|$)')).Value
.Value uses member-access enumeration to extract matching substrings, if any, from the elements of the collection returned by [regex]::Matches().
I've tweaked the regex to use lookaround assertions ((?<=/...) and (?=...)) so that only the substrings of interest are captured.
See this regex101.com page for an explanation of the regex and the ability to experiment with it.
I'm looking to pad IP addresses with 0's
example
1.2.3.4 -> 001.002.003.004
50.51.52.53 -> 050.051.052.053
Tried this:
[string]$paddedIP = $IPvariable
[string]$paddedIP.PadLeft(3, '0')
Also tried split as well, but I'm new to powershell...
You can use a combination of .Split() and -join.
('1.2.3.4'.Split('.') |
ForEach-Object {$_.PadLeft(3,'0')}) -join '.'
With this approach, you are working with strings the entire time. Split('.') creates an array element at every . character. .PadLeft(3,'0') ensures 3 characters with leading zeroes if necessary. -join '.' combines the array into a single string with each element separated by a ..
You can take a similar approach with the format operator -f.
"{0:d3}.{1:d3}.{2:d3}.{3:d3}" -f ('1.2.3.4'.Split('.') |
Foreach-Object { [int]$_ } )
The :dN format string enables N (number of digits) padding with leading zeroes.
This approach creates a string array like in the first solution. Then each element is pipelined and converted to an [int]. Lastly, the formatting is applied to each element.
To complement AdminOfThings' helpful answer with a more concise alternative using the -replace operator with a script block ({ ... }), which requires PowerShell Core (v6.1+):
PSCore> '1.2.3.50' -replace '\d+', { '{0:D3}' -f [int] $_.Value }
001.002.003.050
The script block is called for every match of regex \d+ (one or more digits), and $_ inside the script block refers to a System.Text.RegularExpressions.Match instance that represents the match at hand; its .Value property contains the matched text (string).
I'm returning some data like this in powershell :
1)Open;#1
2)Open;#1;#Close;#2;#pending;#6
3)Closed;#5
But I want an output like this :
1)1 Open
2)
1 Open
2 Close
6 pending
3)
5 Closed
The code:
$lookupitem = $lookupList.Items
$CMRSItems = $list.Items | where {$_['ID'] -le 5}
$CMRSItems | ForEach-Object {
$realval = $_['EventType']
Write-Host "RefNumber: " $_['RefID']
Write-Host $realval
}
Any help would be appreciated as my powershell isn't that good.
Without regular expressions, you could do something like the following:
Ignore everything up to the first ')' character
Split the string on the ';' character
foreach pair of the split string
the state is the first part (ignore potentially leading '#')
the number is the second part (ignore leading '#')
Or you could do it using the .NET System.Text.RegularExpressions.Regex class with the following regular expression:
(?:#?(?<state>[a-zA-Z]+);#(?<number>\d);?)
The Captures property on the MatchCollection returned by the Matches method would be a collection in which each item will contain two instances in the Group collection; named state and number respectively.
Below is a list of data in a single file. I'd like to run this in Powershell.
LESCAR85 07/31/10 1700678991
/ 70039536 $35.00
SQUADCT8 07/31/10 1698125739
/ 70039539 $35.00
RINGFIEL 07/29/10 11041563 /
70039639 $35.00
The 8 digit number and then the dollar amount at the end I would like convert to csv so that I can use that in an excel file. The first set of longer numbers is not always the same which changes the number of spaces between the 8 digit sequence I need and the dollar amount.
Thanks!
As long as ' / ' (slash bounded by spaces) always seperates the data you are interested in from the beginning of the string, then you can use this:
get-content yourDataFile.txt | foreach{(-split ($_ -split ' / ')[1] ) -join ','} > yourResult.csv
What the foreach loop does:
splits each line at the ' / '
Takes the second part of the split (what you are interested in), and splits again at whitespace.
The resulting elements are then joined together using a comma.