How to replace a character at the end of a string/file? - powershell

I'm trying to remove a rogue comma at the end of my file when formatting with PowerShell. The file in question contains the user's city, region, and country.
Example:
San Diego, California, US,
But I want it to be:
San Diego, California, US
How can I remove this last ', ' at the end using -replace?
My code doesn't work below:
(Get-Content file.txt) | ForEach-Object {
$_ -replace ', ', ''
} | Set-Content file.txt
I just need a way of detecting that last ', ' that appears in my file without removing every comma that exists in the file.

You need to anchor your expression at the end of the string. In regular expressions that is done with a $ character. Add a \s* if you want to ignore trailing whitespace after that last comma:
$_ -replace ',\s*$'

You can also simply use the LastIndexOf function of the String class combined with a Substring.
$test = "San Diego, California, US, "
Write-Host $test.Substring(0, $test.LastIndexOf(','))
output: San Diego, California, US
Pretty self explaining --> You select from the start of the string until the last index of your specified char or string.
This is, assuming you always have your rogue comma at the end of the string, otherwise it will trim the text after a "good" comma.

while the regex solution is likely faster than string methods, you can use string methods to do the job. [grin]
use .Trim() to remove any leading or trailing whitespace
use .TrimEnd(',') to remove any trailing comma chars
like this ...
'San Diego, California, US, '.Trim().TrimEnd(',')
output = San Diego, California, US

Related

Renaming the 4th character through the 12th

Here is what I have.
get-childitem "\\myfileserver\out\*" | foreach { rename-item $_ $_.Name.Replace("_123456_837P.", ".").Replace(".test.", ".sa.").Replace("_987654_837I." , ".") }
Here is the filename I want to fix
999_987654_837I.74161.test
I want to remove _987654_837I from the file name. I was just going to rename it but those numbers may change. So now I want to remove the 4th character starting at the _ and back to the "I" or 9th character.
You can use a regex pattern to get the required part.
See regex example + explanation:
https://regex101.com/r/xNoBVD/2
I use positive lookbehind to force regex to get the first 3 characters at the very beginning of the line (^) without capturing it. The following 12 characters are captured and can then be replaced with ''
$regexReplacePattern = '(?<=^.{3}).{12}'
'999_987654_837I.74161.test' -replace $regexReplacePattern, ''

Remove all whitespace, except between quotes

I have been trying to find a way to remove white space from a specific place in a string but have yet to have any luck. I cant just use -Replace to get rid of all white spaces. Ideally I would like to define that everything outside of double quotes gets removed.
I am starting with a string like:
{ [ "Data: I have some data here", "%somedata% == 1234" ] }
And I want it to end up like:
{["Data: I have some data here","%somedata% == 1234"]}
Any ideas on how I can accomplish this?
putting your string into $InStuff, this will replace any 2-or-more spaces with nothing. note that the -replace operator uses regex, while the .Replace() method does not.
$InStuff -replace ' {2,}', ''
output ...
["Data: I have some data here","%somedata% == 1234"]}

In PowerShell, how do I copy the last alphabet characters from a string which also has numbers in it to create a variable?

For example if the string is blahblah02baboon - I need to get the "baboon" seperated from the rest and the variable would countain only the characters "baboon". Every string i need to do this with has alphabet characters first then 2 numbers then more alphabet characters, so it should be the same process everytime.
Any advice would be greatly appreciated.
My advice is to learn about regular expressions.
'blahblah02baboon' -replace '\D*\d*(\w*)', '$1'
Or use regex
$MyString = "01baaab01blah02baboon"
# Match any character which is not a digit
$Result = [regex]::matches($MyString, "\D+")
# Take the last result
$LastResult = $Result[$Result.Count-1].Value
# Output
Write-Output "My last result = $LastResult"

Delete content between 2 lines

I have a pacfile which I am trying to update and need to remove content between two strings; the strings themselves should be kept:
// OFFICE 365 DIRECT ACCESS
and
// END OFFICE 365 DIRECT ACCESS
example:
// OFFICE 365 DIRECT ACCESS
if (isInNet(hostip, "23.103.132.0","255.255.252.0") || //EOP
isInNet(hostip, "23.103.136.0","255.255.248.0") || //EOP
isInNet(hostip, "23.103.144.0","255.255.240.0") || //EOP
isInNet(hostip, "23.103.191.0","255.255.255.0") || //EOP
// END OFFICE 365 DIRECT ACCESS
I want to remove the lines between the top and bottom lines
$Pacfile = Get-ChildItem .\o365.pac | Get-Content -Raw
$startstring= " \/\/ OFFICE 365 DIRECT ACCESS(.*? )\/\/END OFFICE 365 DIRECT ACCESS"
$NewPacfile = [regex]::match($Pacfile, $startstring).Groups[1].value
$NewPacfile
$regex=#'
(?ms)^(\s*// OFFICE 365 DIRECT ACCESS\s*?\r?\n).*?\r?\n(\s*// END OFFICE 365 DIRECT ACCESS\s*)
'#
(Get-Content -Raw .\o365.pac) -replace $regex, '$1$2'
-replace $regex, '$1$2' replaces what the regex matched with what the 1st ($1) and 2nd capture groups ($2) (parenthesized subexpression, (...)) inside of it matched.
Here, these capture groups capture the strings enclosing the range of interest.
(?ms) sets both the multi-line and the single-line option for the regex:
m means that ^ and $ should match the start and end of each line rather than the input string as a whole.
s means that metacharacter . should match \n characters too, so that an expression such as .* can be used to match across lines.
\r?\n matches a single line break, both the CRLF and the LF variety.
.*? matches the part to remove; note the non-greedy modifier (?) following .*, which ensures that the next occurrence of the end string is matched.

Capitalize Specific Words in a String - Powershell

I need to be able to take a sentence in any case and convert it to having the 1st word and each word capitalized except the following words: to, a, the, at, in, of, with, and, but, or
example: "hello how are you dan" needed result: Hello How are You Dan"
Now I know this looks like homework but I am at the point that I need to learn by seeing correct script usage. Lots of effort has been put in to figure out how to do this but I need someone to bridge the gap by showing me the correct method...then I can review it and learn from it.
Windos' answer is spot on, but I'm bored, so here is a fully working implementation:
function Get-CustomTitleCase {
param(
[string]$InputString
)
$NoCapitalization = #(
'are',
'to',
'a',
'the',
'at',
'in',
'of',
'with',
'and',
'but',
'or')
( $InputString -split " " |ForEach-Object {
if($_ -notin $NoCapitalization){
"$([char]::ToUpper($_[0]))$($_.Substring(1))"
} else { $_ }
}) -join " "
}
Use it like this:
PS C:\> Get-CustomTitleCase "hello, how are you dan"
Hello, How are You Dan
$string = 'hello how are you dan to, a, the, at, in, of, with, and, but, or'
[Regex]::Replace($string, '\b(?!(are|to|a|the|at|in|of|with|and|but|or)\b)\w', { param($letter) $letter.Value.ToUpper() })
Regex Explanation:
\b #Start at the beginning of a word.
(?!(are|to|a|the|at|in|of|with|and|but|or) #match only if a word does not begin with "to, a, the, at, in, of, with, and, but, or"
\b #Second \b to signify that there are no characters after the words listed in the negative lookahead list.
\w #Match any single word character
$letter.Value.ToUpper() # convert the matched letter(value) to uppercase
Negative Lookahead
Regex101 Link
I won't give you a complete script, but I can pseudo code this to hopefully put you on the right track.
First of all, create an array of strings containing all the words you don't want to capitalize.
The split the input string ('hello how are you dan') by spaces. You should end up with an array similar to 'hello', 'how', 'are'...
Loop through the split up string, and see if the word is in the first array you created.
If it is, ignore it, but if it isn't you want to take the first letter and use a string method to ensure it is in it's uppercase form.
You then need to join the string back up (don't forget the spaces.) You could either reconstruct the string ready for output as you're looping through the split array or at the end.
(Emphasis added to hint towards certain keywords you'll be after.)