String.TrimStart() doesn't function as I expected, why? - string

I've got the command below:
> "D:\abc\abcName".TrimStart("D:\abc")
Name
In fact I wish this to trim exactly "D:\abc" and return only "abcName" but seems that the 2nd "abc" is trimmed off as well.
Why does this happen and how can I fix it?
I'm using PS 4.0.

The argument to TrimStart() is treated as an array of chars, not a literal string. All consecutive characters at the start of the string that match any of the characters inside the argument "D:\abc" is removed.
You could use the -replace operator instead, which takes a regex pattern as its right-hand argument:
PS C:\> "D:\abc\abcName" -replace "^D:\\abc\\"
abcName
If you are unsure which characters to escape (such as \), let the [regex] class do it for you:
PS C:\> "D:\abc\abcName" -replace "^$([regex]::Escape("D:\abc\"))"
abcName

Mathias R. Jessen points it out.
Looks like you want to get the filename from a path. Instead of using TrimStart consider use the static GetFileNameWithoutExtension method:
[system.io.path]::GetFileNameWithoutExtension("D:\abc\abcName.bat")
Result:
abcName
Or if you want the complete filename with extension:
[system.io.path]::GetFileName("D:\abc\abcName.bat")
Result:
abcName.bat

Related

Drop (substract) last n characters from a variable string length

I need to drop (or replace to nothing) last n characters of a string in powershell code. The variant could be with substraction string form a string (didn't find my answer).
I have something like this (string):
something/something/../lastsomething/NAME
where NAME is a variable text I can extract beforehand and manipulate ($name or $name.length). And the whole string can be counted - $string.length.
How can I substract this NAME from a string ($string)? I've searched many ways, including trim,replace,substring - but all of these mostly work with static words or regex, or with the begining of a string.
I need to get this:
something/something/../lastsomething
I've tried even such constructions:
$string.split('($NAME)')[0]
and
$string.split('[string]($NAME)')[0]
and other with get-AD* functions with join to bypass the strings, but nothing did the trick.
A simple solution is take the substring from beginning (0) to the last occurence of /.
$t = 'something/something/../lastsomething/NAME'
$t.Substring(0, $t.LastIndexOf('/'))
EDIT from your comment the real question is how to get
-replace '($_.Name)',' '
working. The single quotes don't expand variables - so use double quotes.
To force evaluation of $_.Name you have to enclose it with $()
-replace "/$($_.Name)"
With an unknown last element /Name
> $String = 'something/something/../lastsomething/NAME'
> $String.Split('/')[-1]
NAME
> $string = $string -replace "/$($String.Split('/')[-1])"
> $string
something/something/../lastsomething
A much simpler solution is :
> Split-Path $string
something\something\..\lastsomething
> Split-Path $string -Leaf
NAME
but it changes slashes to backslashes
You can replace it with '' (nothing ... empty string) and because -replace works with regular expressions you can make sure that you only get a "match" at the end of the string like this:
$var = '/NAME'
'something/Name/something/../lastsomething/NAME' -replace "$var$",''

Powershell removing characters from string up to last separator

I have a string
Projects\TestEnvironment\11111xx\1111111
and need to get 1111111 from it. What I'm doing now is:
$name = $dir.Substring($dir.IndexOf('\')+1)
where $dir is my string, however it only removes up to first string, is it possible to change direction?
What about using split-path?
$string = 'Projects\TestEnvironment\11111xx\1111111'
Split-Path $string -Leaf
returns 1111111.
Note the -Leaf parameter indicates that this cmdlet returns only the last item or container in the path.
#Robin's answer is good if the string is always a path (separated with "\"); in the general case, where the delimiter may be a different character, you can use
$string = "This-is-a-string-with-delimiters"
$lastword = ($string -split "-")[-1]
The -split operator defaults to splitting on a space, but will split on any character you choose to pass it, returning an array of strings, each string being the material before/between/after delimiters - in the example above, each word would be in a separate string in the array. Negative subscripts to an array count from the end of the array rather than the start, and are 1-origin rather than 0-origin - so $x[-1] is the last element of the array $x.
This technique also works on paths;
$path = "C:\Users\JSmith\Documents\Resume.doc"
$filename = ($path -split "\\")[-1]
will give you $filename -eq Resume.doc. Note that the delimiter passed to -split in this case is escaped, because the delimiter can be a regular expression, and the backslash ("\") is meaningful in regular expressions (it's the character that indicates that another meaningful character is to be "escaped", or its meaning ignored).
other solution
('Projects\TestEnvironment\11111xx\1111111' -split '\\')[-1]
or
'Projects\TestEnvironment\11111xx\1111111'.Split('\')[-1]

Powershell Search String in File Containing $

I want to search the following string in a text file: $$u$$
I tried select-string, get-content, .Contains. It seems to me it's not possible.
I used this for the search as a variable: $ToSearch = "'$'$u'$'$"
It always gives false result.
It is because most search filters are relying on regex. The $ symbol in regex needs to be escaped
Without knowing more of what you're trying to accomplish I can't give much of an example, but here is one:
'this is a $$u$$ test' -replace "\$",""
The '\' is what is escaping the character - meaning to translate it literally.
Edit: Per comment
$Val = 'this is a $$u$$ test'
$Val | Select-String "\$+\w\$+" -quiet
-Quiet switch returns t/f rather than a string value.
The $ is a reserved character in regex, which is complicating your search.
The default search pattern type for Select-String is regex, but you can also specify -Simplematch or -Wildcard, either of which will eliminate the need to escape the $. If you use -Wildcard, you'll need to include the wilcard * at either end of the match - '*$$u$$*'. For simplematch, just use the string you want to match for - '$$u$$'.

Drop last section of string in powershell

I have found many ways in Powershell to capture the sections of strings using split(), but I am stumped on this one. Using the example string below:
"Monkey/Zebra/Bird/Bird"
I am able to capture the end "Bird" using the code below:
$path = "Monkey/Zebra/Bird/Bird"
$animal = $path.split("/")[-1]
My end goal is to be able to capture the front of the string, without the last "split", so to output:
"Monkey/Zebra/Bird"
The number of "Animals" will vary, so I cannot hard code the number of characters or "/" to look for.
Using a regular expression with -replace:
$text = "Monkey/Zebra/Bird/Bird"
$text -replace '/[^/]+$'
Monkey/Zebra/Bird
I would probably use a regex too, but if you wanted to use a split:
("Monkey/Zebra/Bird/Bird" -split '/')[0..((("Monkey/Zebra/Bird/Bird" -split '/').count)-2)] -join '\'
I love Perl...errr Powershell
You could use a for each command such as
$path = "Monkey/Zebra/Bird/Bird"
foreach($animal in $path.split("/"))
{
Write-Host $animal
}
This will then split the path and process each animal in turn
I preface this with the fact that RegEx is probably your fastest answer. That said...
Another approach, using split, to get only one of each animal since your example was parsing out the duplicate "bird" from "Monkey/Zebra/Bird/Bird"
$Animals = "Monkey/Zebra/Bird/Bird"
($Animals.Split('/')|Select -Unique) -join '/'
Or if you just want to drop the last part you can do what EBGreen suggested, split it into individual animals, count those, return all but the last one, and re-join them together.
($Animals.Split('/'))[0..($Animals.Split('/').count-2)] -join '/'
Either of those will return Monkey/Zebra/Bird but if you like the latter of the options please attribute the answer to EBGreen.
$path = "Monkey/Zebra/Bird/Bird"
$path -replace '/\w+$'
Monkey/Zebra/Bird

How to split the string and retrieve last two columns in perl

i want to retrive the last two columns of a string
ex
$path = C:\Documents and Settings\ac62599\AC62599_SBI_Release_2012.12.1_int\vob\SBI_src
$path = C:\views\ac62599\AC62599_view\vob\aims
output should be
\vob\SBI_src
\vob\aims
output should come like this . Thanks in advance
Use split to split the paths into directories. You can use a slice to get the last two, then use join to concatenate them back:
for my $path ('C:\Documents and Settings\ac62599\AC62599_SBI_Release_2012.12.1_int\vob\SBI_src',
'C:\views\ac62599\AC62599_view\vob\aims') {
print '\\', join('\\', (split/\\/, $path)[-2, -1]), "\n";
}
A regex seems to be the simplest solution
my ($dir) = $path =~ /((?:\\[^\\]+){2})$/;
Which is to say, look for backslash, followed by one or more non-backslash characters, and look for this sequence twice at the end of the string and capture it.
Note the use of parentheses around the variable is required to give the regex list context.
Output for the sample paths:
\vob\SBI_src
\vob\aims
$string=~m/.*(\\[^\\]*\\[^\\]*)/g;print $1

Resources