Append comma to every element in the Arraylist of strings - powershell

I need to append comma to every string , my code appending "," to last element as well how to eliminate that
for($j=0; $j -lt $back_log_bloblist.Count; $j++){
if($back_log_bloblist[$j].Name -like "$Value"){
$string += $back_log_bloblist[$j].Name +","
Write-Host $string
}
}

This can be solved much easier without an explicit loop:
$string = ($back_log_bloblist.Name -like $Value) -join ','
Explanation:
$back_log_bloblist.Name creates an array from the values of the Name property of all $back_log_bloblist elements
-like $Value selects all elements from this array that match pattern in $Value
-join ',' finally joins all selected elements (inserting commas only between elements, not after, exactly what you want)
you could remove the brackets, they are just there for conceptual clarity
Proof-of-concept:
$back_log_bloblist = [pscustomobject]#{ Name='foo' },
[pscustomobject]#{ Name='fop' },
[pscustomobject]#{ Name='bar' }
$Value = 'f*'
$string = ($back_log_bloblist.Name -like $Value) -join ','
$string
Output:
foo,fop

Related

How to combine string inputs and generate array dynamically?

param([string]$roles,[string]$members)
Suppose I am passing input on the command line like this:
PS> role1,role2,role3,role4 member1,member2,,,,member3,,member4
The array I expect for this would be:
$array = #(
#('role1', 'member1,member2'),
#('role2', ''),
#('role3', 'member3'),
#('role4', 'member4')
)
I know to turn string to array:
$roles = 'role1,role2,role3,role4' -split ','
$members = 'member1,member2,,,,member3,,member4' -split ',,'
Now how do I combine $roles with $members so that each role will be associated with member(s)? and how wouldIi generate the array dynamically?
Pseudocode:
$array = #()
($roles+$members) | %{
$role = $_.roles
if ($_.members) {
$_.members -split ',,' | ForEach-Object { $array += $role $_ }
} else {
$array += $role
}
}
Note: I am splitting members as an index of its own for each double comma because apparently semicolons aren't accepted on a command line because they break the command line, so I have to use double comma as delimiter.
Note 2: notice the 4 commas: ,,,, this indicates that role2 does not have members to add, so in essence it means between the 4 commas is no input for member to that index/item (role2), i.e. ,,EMPTY,,.
If you really want to stick with this parameter format, you can create the desired output array as follows:
$roles = 'role1,role2,role3,role4' -split ','
$members = 'member1,member2,,,,member3,,member4' -split ',,'
$i = 0
$array = #(foreach ($role in $roles) {
, ($role, $members[$i++])
})
Note that if you pass your arguments from PowerShell, you need to quote them, as PowerShell will otherwise parse them as an array.
And with quoting you're free to use ; in lieu of ,,, for instance, to separate the member groups.
A better way to represent the argument data for later processing is to create an array of custom objects rather than a nested array:
$roles = 'role1,role2,role3,role4' -split ','
$members = 'member1,member2,,,,member3,,member4' -split ',,'
$i = 0
$array = #(foreach ($role in $roles) {
[pscustomobject] #{
Role = $role
Members = $members[$i++] -split ','
}
})
Each object in $array now has a .Role and a .Members property, the latter containing the individual members as a an array of strings.
Alternatively, you could create a[n ordered] hashtable from the input, keyed by role name, but that is only necessary if you need to access roles by name or if you wanted to rule out duplicate roles having been specified.
Here's an alternative argument format that is easier to understand:
$rolesAndMembers = 'role1 = member1,member2 ; role2= ; role3=member3 ; role4=member4'
$array = #(foreach ($roleAndMembers in ($rolesAndMembers -replace ' ' -split ';')) {
$role, $members = $roleAndMembers -split '='
[pscustomobject] #{
Role = $role
Members = $members -split ','
}
})
Your parameter format is rather bizarre, but here's one way:
$roles = 'role1,role2,role3,role4' -split ','
$members = 'member1,member2,,,,member3,,member4' -split ',,'
$result = #()
for ( $i = 0; $i -lt $roles.Count; $i++ ) {
$result += ,#($roles[$i],$members[$i])
}
I would recommend redesigning the script to use standard PowerShell parameters (the engineering effort would be worth it, IMO).
I'd strongly recommend using hashtables/dictionaries to pass these role mappings:
param(
[System.Collections.IDictionary]$RoleMembers
)
# now we can access each mapping by role name:
$RoleMembers['role1'] # member1, member2
# or iterate over them like an array:
foreach($role in $RoleMembers.Keys){
$RoleMembers[$role]
}
You could use one of the construct the input argument from your current input strings:
$roles = 'role1,role2,role3,role4' -split ','
$members = 'member1,member2,,,,member3,,member4' -split ','
$roleMembers = #{}
for ($i = 0; $i -lt $roles.Count; $i++) {
# `Where Length -ne 0` to filter out empty strings
$roleMembers[$roles[$i]] = $members[($i*2)..($i*2+1)] |Where Length -ne 0
}

Powershell sort string elements delimited by semicolons

I have a string wit a following content, delimited by semicolons:
echo $content
BCS3;BCS2;DigitalIO;GAElectricDrive;J1939;SKF15;UBloxGNSS;VIMS
Perhaps my question is noob, but I cannot figure out, how to sort this values alphabetically, e.g. I want to receive following output(first and second elements are not in alphabetical order):
BCS2;BCS3;DigitalIO;GAElectricDrive;J1939;SKF15;UBloxGNSS;VIMS
$Content = "BCS3;BCS2;DigitalIO;GAElectricDrive;J1939;SKF15;UBloxGNSS;VIMS"
$Content = ($Content -split ';'|Sort) -Join ';'
$content
BCS2;BCS3;DigitalIO;GAElectricDrive;J1939;SKF15;UBloxGNSS;VIMS
But the sorting is alphabetical, words containing numbers with differing places are sorted 1,10,100,2,20,200.
To avoid this you can use $ToNatural
$ToNatural = { [regex]::Replace($_, '\d+', { $args[0].Value.PadLeft(20) }) }
$Content = "1;10;100;2;20;200"
$Content = ($Content -split ';'|Sort $ToNatural) -Join ';'
$content
1;2;10;20;100;200

Retrieving second part of a line when first part matches exactly

I used the below steps to retrieve a string from file
$variable = 'abc#yahoo.com'
$test = $variable.split('#')[0];
$file = Get-Content C:\Temp\file1.txt | Where-Object { $_.Contains($test) }
$postPipePortion = $file | Foreach-Object {$_.Substring($_.IndexOf("|") + 1)}
This results in all lines that contain $test as a substring. I just want the result to contain only the lines that exactly matches $test.
For example, If a file contains
abc_def|hf#23$
abc|ohgvtre
I just want the text ohgvtre
If I understand the question correctly you probably want to use Import-Csv instead of Get-Content:
Import-Csv 'C:\Temp\file1.txt' -Delimiter '|' -Header 'foo', 'bar' |
Where-Object { $_.foo -eq $test } |
Select-Object -Expand bar
To address the exact matching, you should be testing for equality (-eq) rather than substring (.Contains()). Also, there is no need to parse the data multiple times. Here is your code, rewritten to to operate in one pass over the data using the -split operator.
$variable = 'abc#yahoo.com'
$test = $variable.split('#')[0];
$postPipePortion = (
# Iterate once over the lines in file1.txt
Get-Content C:\Temp\file1.txt | foreach {
# Split the string, keeping both parts in separate variables.
# Note the backslash - the argument to the -split operator is a regex
$first, $second = ($_ -split '\|')
# When the first half matches, output the second half.
if ($first -eq $test) {
$second
}
}
)

I want to check if an element exist in an array

I want to check if a element exist in an array.
$data = "100400296 676100 582"
$i = "18320-my-turn-582"
if ($data -like $i) { Write-Host "Exist" }
else { Write-Host "Didn't exist" }
This example doesn't work like I want it. $i contains 582, so I want it to be Exist in result.
Your string "18320-my-turn-582" doesn't exist in $data, even though both strings contain the substring 582.
PowerShell treats your strings as a whole, and 18320-my-turn-582 is not present in 100400296 676100 582. To work around this you can:
Use Regex:
$i -match '\d+$'
$data -match $Matches[0]
Split the $i at hyphens so you will have:
$i = $i -split '-'
# turns $i into a array with the elements:
# 18320
# my
# turn
# 582
$data -match $i[-1]
# Output: 100400296 676100 582
Check out Get-Help about_Comparison_Operators to understand the differences between -Contains, -Match and -Like operators.

How to create an associative array, preferably a one-liner?

I have this:
$str = "name = username`nemail = user#example.com"
Which is LF separated string, as part of an INI file. I want to create associative array so that for instance $vars['name'] will return 'username'. This is how I split it to lines:
$vars = ([regex]'\n').Split($str) | %{ $_.Trim() }
What change should I make to the line above?
If you are a lucky owner of Powershell 4 then you can use ConvertFrom-StringData cmdlet:
$str = "name = username`nemail = user#example.com"
$vars = ConvertFrom-StringData $str
Result:
PS C:\> $vars
Name Value
---- -----
name username
email user#example.com
A more PoSh version of PeterK's answer would look like this:
$vars = #{}
$str.Trim() -split "\s*`n\s*" | % {
$key, $value = $_ -split '\s*=\s*'
$vars[$key] = $value
}
Using $vars[$key] = $value instead of $vars.Add($key, $value) avoids errors in case you have duplicate keys.
You could also split the string into an array of alternating key and value fields and then fill the hashtable from that array:
$vars = #{}
$list = $str.Trim() -split "\s*`n\s*" -split '\s*=\s*'
while ($list) {
$key, $value, $list = $list
$vars[$key] = $value
}
Each of the examples can be mangled into a single line by separating the statements with semicolons:
$vars = #{}; $str.Trim() -split "\s*`n\s*" | % { $key, $value = $_ -split '\s*=\s*'; $vars[$key] = $value }
$vars = #{}; $list = $str.Trim() -split "\s*`n\s*" -split '\s*=\s*'; while ($list) { $key, $value, $list = $list; $vars[$key] = $value }
It's not a one-liner, but one way to do it is:
$hashtable = #{};
$key_value_pairs = $str.Split("`n");
foreach($key_value in $key_value_pairs)
{
$key_value_pair = $key_value.Split('=');
$hashtable.Add($key_value_pair[0].Trim(), $key_value_pair[1].Trim());
}
The input string is first split into an array, each item containing a key-value pair in a single line. For each key-value pair, we split them into a 'key' and 'value' on "=", again into a regular array. Both the key and value are trimmed and added to the hash table. Once this is done, $hashtable["name"] will return "username" and $hashtable["email"] will return "user#example.com"