No result from Substring - powershell

Hey guys i´m just starting with powershell, now I´ve got this problem. I try to check wheater the last character of a inputed path is a "\". But when I run this code the variable $lastRootPathChar is empty. The $end and $start variables get the integers I want them to have, but the .Substring seems to return nothing. What am I doing wrong?
$RootPath = Read-Host 'Please enter the rootpath: '
$start = $RootPath.Length-1
$end = $RootPath.Length
$lastRootPathChar = $RootPath.Substring($start,$end)
if($lastRootPathChar -ne "\")
{
$RootPath = $RootPath + "\"
}

The two parameters passed to that overload of String.Substring are start and length not start and end
$lastRootPathChar = $RootPath.Substring($start,1)

The second argument to "".Substring() is the total length of the desired substring, not the end index.
$LastChar = $RootPath.Substring($start, 1)
You could also use the index operator [] to access the last char in the string (index -1):
$LastChar = $RootPath[-1] -as [string]

$lastRootPathChar = $RootPath.Substring($RootPath.length -1)
This will get the slash out. As $RootPath.length -1 is the index of the last character and there are no characters after that.

Related

Truncate, Convert String and set output as variable

It seems so simple. I need a cmdlet to take a two word string, and truncate the first word to just the first character and truncate the second word to 11 characters, and eliminate the space between them. So "Arnold Schwarzenegger" would output to a variable as "ASchwarzeneg"
I literally have no code. My thinking was to
$vars=$var1.split(" ")
$var1=""
foreach $var in $vars{
????
}
I'm totally at a loss as to how to do this, and it seems so simple too. Any help would be appreciated.
Here is one way to do it using the index operator [ ] in combination with the range operator ..:
$vars = 'Arnold Schwarzenegger', 'Short Name'
$names = foreach($var in $vars) {
$i = $var.IndexOf(' ') + 1 # index after the space
$z = $i + 10 # to slice from `$i` until `$i + 10` (11 chars)
$var[0] + [string]::new($var[$i..$z])
}
$names

How to find the positions of all instances of a string in a specific line of a txt file?

Say that I have a .txt file with lines of multiple dates/times:
5/5/2020 5:45:45 AM
5/10/2020 12:30:03 PM
And I want to find the position of all slashes in one line, then move on to the next.
So for the first line I would want it to return the value:
1 3
And for the second line I would want:
1 4
How would I go about doing this?
I currently have:
$firstslashpos = Get-Content .\Documents\LoggedDates.txt | ForEach-Object{
$_.IndexOf("/")}
But that gives me only the first "/" on each line, and gives me that result for all lines at once. I need it to loop where I can figure out the space between each "/" for each line.
Sorry if I worded this badly.
You can indeed use the String.IndexOf() method for this!
function Find-SubstringIndex
{
param(
[string]$InputString,
[string]$Substring
)
$indices = #()
# start at position zero
$offset = 0
# Keep calling IndexOf() to find the next occurrence of the substring
# stop when IndexOf() returns -1
while(($i = $InputString.IndexOf($Substring, $offset)) -ne -1){
# Keep track of the index at which the substring was found
$indices += $i
# Update the offset, we'll want to start searching for the next index _after_ this one
$offset = $i + $Substring.Length
}
}
Now you can do:
Get-Content listOfDates.txt |ForEach-Object {
$indices = Find-SubstringIndex -InputString $_ -Substring '/'
Write-Host "Found slash at indices: $($indices -join ',')"
}
An concise solution is to use [regex]::Matches(), which finds all matches of a given regular expression in a given string and returns a collection of match objects that also indicate the index (character position) of each match:
# Create a sample file.
#'
5/5/2020 5:45:45 AM
5/10/2020 12:30:03 PM
'# > sample.txt
Get-Content sample.txt | ForEach-Object {
# Get the indices of all '/' instances.
$indices = [regex]::Matches($_, '/').Index
# Output them as a list (string), separated with spaces.
"$indices"
}
The above yields:
1 3
1 4
Note:
Input lines that contain no / instances at all will result in empty lines.
If, rather than strings, you want to output the indices as arrays (collections), use
, [regex]::Matches($_, '/').Index as the only statement in the ForEach-Object script block; the unary form of ,, the array constructor operator ensures (by way of a transient aux. array) that the collection returned by the method call is output as a whole. If you omit the , , the indices are output one by one, resulting in a flat array when collected in a variable.

How to get the index of the last occurence of a char in PowerShell string?

I want to get the index of the last "\" occurrence in order to trim the "Activity" word and keep it, from following string in PowerShell:
$string = "C:\cmb_Trops\TAX\Auto\Activity"
I'm converting the code from VBScript to PowerShell and in VB there's this solution :
Right(string, Len(string) - InStrRev(string, "\"))
Using Right and InStrRev functions which makes the life more easier. Unfortunately I didn't find anything like it in PowerShell. Can't find any option to scan from the end of the string.
$String.Split("\")[-1]
Or if $String is actually a real path, you might consider:
Split-Path $String -Leaf
$string = "C:\cmb_Trops\TAX\Auto\Activity"
$string = $string.Substring($string.lastIndexOf('\') + 1)
echo $string
Check out:
https://community.spiceworks.com/topic/1330191-powershell-remove-all-text-after-last-instance-of

Only split on the first occurence of a character

If I have a string like
foo:bar baz:count
and I want to split on the first occurrence of : and get an array returned which contains only two elements:
A string which is the element before the first colon.
A string which is everything after the first colon.
How can I achieve this in Powershell?
-split operator allows you to specify maximum number of substrings to return:
'foo:bar baz:count' -split ':',2
Using IndexOf() to find first occurance of ':'
Take the substring from the beginning until the index of ':'
Take the rest of the string from the ':' to the end.
Code:
$foobar = "foo:bar baz:count"
$pos = $foobar.IndexOf(":")
$leftPart = $foobar.Substring(0, $pos)
$rightPart = $foobar.Substring($pos+1)

Remove first and last three character of a word with powershell

I have a list of users in a text file who's names are in the following format: xn-tsai-01.
How do I script to remove the xn- KEEP THIS -01 so the output is like: tsai
I know how to do this in bash but not too familiar with powershell.
Thanks in advance!
Why not use Substring method. If you will always trim the first three characters, you can do the following assuming the variable is a string type.
$string = xn-tsai-01
$string.Substring(3)
Here is a quick way to do it using regex:
'xn-tsai-01' -replace '.*?-(.*)-.*','$1'
Example with a list:
(Get-Content list.txt) -Replace '.*?-(.*)-.*','$1'
You can use the .NET string method IndexOf("-") to find the first, and LastIndexOf("-") to find the last occurrence of "-" within the string.
Use these indexes with Substring() to remove the unnecessary parts:
function Clean-Username {
param($Name)
$FirstDash = $Name.IndexOf("-") + 1
$LastDash = $Name.LastIndexOf("-")
return $Name.Substring( $f, $l - $f )
}
PS C:\> Clean-UserName -Name "xn-tsai-01"
tsai
Boe's example is probably going to be the most efficient.
Another way is to use the split() method if they're in a uniform format.
Get-Content .\list.txt | % { ($_.Split('-'))[1] }
% is an alias for ForEach