Split a string to multiple strings in powershell - powershell

I have strings like
$value = "1;#Mohapatra,Mrutyunjaya (ADM) 10;#Sumit Upadhyay(ADM) 11;#Naidu,Ishan(ADM)"
I want to retrieve
"Mohapatra,Mrutyunjaya (ADM)", "Sumit Upadhyay(ADM)", "Naidu,Ishan(ADM)"
from $value.
I have tried $value.Split(";#")[0]. It is returning the first parameter only. But I want all the parameters

Split your string at sequences of \s*\d+;# (optional whitespace, followed by a number, a semicolon, and a hash character), and remove empty elements from the resulting list:
$value -split '\s*\d+;#' | Where-Object { $_ }

Just FYI, if you want to declare each as a variable you can say $a,$b,$c,$d = $Value -Split (";#") and each of $a, $b, $c and $d will retain those values.

Related

Powershell - How to Transpose an array

I have an array with data separated by a comma. I need to transpose it so the first part before the comma for each line is joined together by a delimiter as one line and the same for a second part. Example:
AC-2.22,CCI-000012
AC-5.1,CCI-000036
AC-5.3,CCI-001380
I want to have 2 separate variables like so:
variable 1 = AC-2.22; AC-5.1; AC-5.3
Variable 2 = CCI-000012; CCI-000036; CCI-001380
I know this should be simple but I've been staring at code all day and I just want to go eat dinner and goto sleep.
Thanks in advance
Based on the $array of the helpful answer from Santiago Squarzon, you might also use the ConvertFrom-Csv cmdlet to transpose the data using member-access enumeration:
$data = ConvertFrom-Csv $Array -Header var1, var2
$data.var1 -Join ';'
AC-2.22;AC-5.1;AC-5.3
$data.var2 -Join ';'
CCI-000012;CCI-000036;CCI-001380
This is not too hard using .Where method with Split mode:
$array = #(
'AC-2.22,CCI-000012'
'AC-5.1,CCI-000036'
'AC-5.3,CCI-001380'
)
$i = $false
$var1, $var2 = $array.Split(',').Where({ ($i = -not $i) }, 'Split')
$var1 -join '; '
$var2 -join '; '
.Split method works in this case thanks to Member-Access Enumeration, because arrays don't have an .Split method the same is called over each element of the array:
When you use the member-access operator on any object and the specified member exists on that object, the member is invoked. For property members, the operator returns the value of that property. For method members, the operator calls that method on the object.
When you use the member-access operator on a list collection object that doesn't have the specified member, PowerShell automatically enumerates the items in that collection and uses the member-access operator on each enumerated item.

powershell How to capture 'left side' of the -replace regex?

First time posting.
i have the following code to replace the suffix of an email and its working fine
replace all characters after # sign with #testdomain.com
$a = 'john.doe#domain.com'
$b = $a -replace "[?=#].*", '#testdomain.com'
$b
john.doe#testdomain.com
what i would like to do, is to capture the actual left side 'source' regex expression to a variable, which would be #domain.com so that i know what i;m replacing and i don;t know how to do it.
Sorry if this had been posted before.
Thank you
So, I'm not sure if this is possible using only the -replace operator and without the use of -match which would store the capture group on the $Matches automatic variable.
This is how you could do it using the regex class directly:
$a = 'john.doe#domain.com'
$Capture = #{}
$b = [regex]::Replace($a, "[?=#].*", {
param($s)
'#testdomain.com'
$Capture.Value = $s.Value
})
$b # => john.doe#testdomain.com
$Capture.Value # => #domain.com
This what I could think using only -replace, adding a delimiter (// in this case) to the replaced string followed by the capture group $0 and then splitting the replacement. Though, this is obviously not a robust solution.
$a = 'john.doe#domain.com'
$b, $capture = $a -replace "[?=#].*", '#testdomain.com//$0' -split '//'
$b # => john.doe#testdomain.com
$capture # => #domain.com
To change the user part you can replace ^.*(?=#):
PS ~> $a = 'john.doe#domain.com'
PS ~> $a -replace '^.*(?=#)', 'jane.doe'
jane.doe#domain.com
The (?=#) construct is known as a lookahead, and describes a zero-length string at the position immediately before the #.

Why is '^\S' not working for first character or NULL value?

I have a variable that is holding two values from a table (using -expandproperty)
$variable = "value1,value2"
I have a check to make sure $variable doesnt have any NULL/empty value returned
if(($variable.Split(",") | Where { $_ -match '^\S'}).count -lt 1)
{write "no value!"}
else
{write $variable}
but for some reason, even though '^\S' is supposed to ONLY check the first character/index for a whitespace, it outputs "
no value
" condition result...it should be outputting
value1,value2
instead...
not only that, but if the table column value is NULL, it doesnt recognize it and instead tried to output the second condition write $variable
why is that??
another way to check for "null or empty" is to use the [string]IsNulOrEmpty() static method. something like this ...
$Var1 = "value1,value2"
$Var2 = ''
$Var3 = $Null
$Var1, $Var2, $Var3 |
ForEach-Object {
$_
[string]::IsNullOrEmpty($_)
}
output ...
value1,value2
False
True
True
note that the final $Null did not produce a new line, while the 2nd item [an empty string] did.
\S is nonwhite space.
\s is whitespace.

Pass String Variable to Function Argument as Comma Separated List

I've got a PowerShell function that accepts multiple values for a single argument via a comma separated list, like so:
test-function -Targets 127.0.0.1, 8.8.8.8, fake.fqdn.com -FileName "c:\results.csv"
Here is the param section:
function test-function {
param(
[string[]]$Targets
[string]$FileName
)
}
I'm trying to put an array in as multiple Target arguments, so I've put them into a single variable like so:
foreach ($target in $arrayTargets) { $temp = $temp + ", $Target" }
$Targets = $temp -replace "^, ", ""
This would result in the required "127.0.0.1, 8.8.8.8, fake.fqdn.com" as a string in the variable $Targets.
When I try to execute the function referencing the $Targets variable, the function interprets $Targets as if it's a single entry, not multiple. This is what I've tried with the same results:
test-function -Targets $Targets -FileName "c:\results.csv"
test-function -Targets "$Targets" -FileName "c:\results.csv"
I've also tried an ArgList several different ways:
$ArgList = "-Targets $Targets -FileName `"c:\results.csv`""
test-function $ArgList
Instead of taking each individual array entry as an argument, it takes the entire string as the argument.
How can I get this function to accept an array as multiple targets?
If you have an array of arguments, there should be no reason to pack them into a string to pass to your function. Simply pass the array.
test-function -Targets $arrayTargets
To assign an array of values to a variable in PowerShell, simply assign a comma-separated list. Note to make an array of strings, you should make sure to put the strings in quotes (single or double). All of the following are equivalent.
$arr = #("127.0.0.1", "8.8.8.8", "fake.fqdn.com")
$arr = ('127.0.0.1', '8.8.8.8', 'fake.fqdn.com')
$arr = "127.0.0.1", '8.8.8.8', "fake.fqdn.com"
If you need your array to convert to a comma-separated string for any reason, there's no need to build it with a foreach loop. Instead use the -join operator.
PS> $string = $arr -join ', '
PS> $string
127.0.0.1, 8.8.8.8, fake.fqdn.com
But you will probably only want your array in this form to display it. As shown above, it's best to keep it in array form to pass to a function. You can even get the array back from the string using the -split operator.
PS> $string -split ', '
127.0.0.1
8.8.8.8
fake.fqdn.com

Count number of spaces, and split at the last one

I have a string simliar to:
c:/folder name/somewhere/application.exe instanceName
(n.b. the space in "folder name" is intentional) I need a way to split this into:
[0]c:/folder name/somewhere/application.exe
[1]instanceName
I was going to use split-path, but apparently there is a bug in powershell v2 that stops me doing this:
Split-Path : Cannot find drive. A drive with the name '
So, I figured if I count how many spaces there are, and then simply use -split() to split it at the last space.
But, I can't see how to count the number of spaces.
I've found lots of examples that talk about using regex to count complex strings, but I just want to count spaces!
Tonnes of ways to do this I imagine but to use your split idea you could do the following.
$split = "c:/folder name/somewhere/application.exe instanceName".Split(" ")
$path = $split[0..($split.count -2)] -Join " "
$instance = $split[-1]
Split the sting by spaces. The number of spaces is represented by the count of strings in the array $split. We join all the strings in the array accept the last intp $path then we take the last entry and assign it to $instance
You could also use .substring and .lastindexof
$string = "c:/folder name/somewhere/application.exe instanceName"
$index = $string.LastIndexOf(" ")
$string.Substring(0,$index)
$string.Substring($index + 1)
I can't see a way to split this directly into an array at this time but outputing as an array would not be a big deal.
$path, $instance
or
$array = #($path,$instance)
You can use a regular expression for this:
$s = "c:/folder name/somewhere/application.exe instanceName"
$s -match '(.*) (.*)$'
$matches[1]
$matches[2]
The special variable $matches is populated if the -match operation is true.
$matches[0] contains the original string, and other indexes will exist for the number of groups (patterns in parenthesis) in the regex. In this case: (.*) (.*)$ we have two groups.