How to replace a string between two other strings - powershell

I am trying to replace in several files the following type of string:
StringResourceHelper.[STRING_OF_INTEREST]ResourceString()
with
Strings.[STRING_OF_INTEREST]
For example I would like to replace:
StringResourceHelper.HelpResourceString() with Strings.Help
So far, I got a simple replacement which would work if the second string would not be important:
Get-ChildItem . *.cs -Recurse |
Foreach-Object {
$c = ($_ | Get-Content)
$c = $c -replace 'StringResourceHelper.','Strings.'
$c | Set-Content $_.FullName -Encoding UTF8
}
But this does not help me, because I also have Strings like StringResourceHelper.Culture which should not be touched.
Any help is appreciated.

You need to escape literal dots in your regular expression, otherwise . will match any character except newlines. Something like this should work:
$c = $c -replace 'StringResourceHelper\.(\w*?)ResourceString\(\)', 'Strings.$1'
Also, your code could be simplified a little, like this:
$srch = 'StringResourceHelper\.(\w*?)ResourceString\(\)'
$repl = 'Strings.$1'
Get-ChildItem . *.cs -Recurse | % {
$filename = $_.FullName
(Get-Content $filename) -replace $srch, $repl |
Set-Content $filename -Encoding UTF8
}

Related

How to Select-String with pattern that contains $value

How to search for a string that starts with $ in a txt file?
For example:
Get-Content $file | Select-String -pattern 'VALUE="$USERPROFILE"'
Thanks
Either use the [regex]::Escape() method to correctly escape verbatim strings for use in regex patterns:
$pattern = 'VALUE="{0}"' -f [regex]::Escape('$USERPROFILE')
Get-Content $file | Select-String -Pattern $pattern
or use the -SimpleMatch switch to indicate you don't wanna use regex at all:
Get-Content $file | Select-String -pattern 'VALUE="$USERPROFILE"' -SimpleMatch
If you only want to find strings that start with '$', you can use an approach similar to the one below.
param(
[string] $file = "$PSScriptRoot\test.txt",
[string] $pattern = "$*"
)
$stringsBeginningWithPattern = (Get-Content $file).Split() | Where-Object {
$_ -like $pattern
}
$stringsBeginningWithPattern

Power shell code to remove special characters in the column headers(.csv file)

I'm trying to loop through 40 CSV files in a path and remove any characters that are not numeric,alphabets and space values only in the headers.
Below is my code i tried working on, This is working for headers in the files but also its replacing all the data in the file and i can see only headers without special characters in it, i'm just a beginner in power shell, not sure how to proceed further any help is much appreciated.
$path = "C:\AllFiles\"
Get-ChildItem -path $path -Filter *.csv |
Foreach-Object {
$content = Get-Content $_.FullName
$content[0] = $content[0] -replace '[^0-9a-zA-Z, ]'|Set-Content $_.FullName
}
The -replace operator requires two values, the first value is what you are looking for, and the second value is what to replace the first value with.
EXAMPLE:
"John Jones" -replace "Jones","Smith"
This will replace "Jones" with the text "Smith" creating a new string "John Smith"
In your example, instead of creating a regex of what you want to keep, create a regex of what you want to replace.
EXAMPLE:
$path = "C:\AllFiles\"
Get-ChildItem -path $path -Filter *.csv |
Foreach-Object {
$content = Get-Content -Path $path
$content[0] = $content[0] -replace '[regex for special chars]',""
Set-Content $path -value $content -force
}
This will replace the whole string, with a string where you've replaced the regex values with ""
This should do the trick and should be the fastest method:
$path = 'C:\AllFiles\'
$collection = Get-ChildItem -path $path -Filter *.csv'
foreach( $file in $collection ) {
$content = [System.IO.File]::ReadAllLines( $file.FullName )
$content[0] = $content[0] -replace '[^0-9a-zA-Z, ]'
[System.IO.File]::WriteAllLines( $file.FullName, $content ) | Out-Null
}
Pretty close, try it like this instead:
$path = "C:\temp"
Get-ChildItem -path $path -Filter *.csv |
Foreach-Object {
$content = Get-Content $_
$content[0] = $content[0] -replace '[^a-zA-Z0-9, ]',''
$content | Out-File $_
}
This will only clear special characters on the first line but leaves the rest of the file untouched.
Try this:
dir "C:\AllFiles" -Filter *.csv | % {
(Get-Content $_.FullName)[0] -replace '[\W]', '' | Set-Content $_.FullName -Force
}

Powershell Remove all lines except those containing certain strings

I can do this one-by-one with bookmarking and other Notepad++ features, but I will be doing this frequently to edit documents. I have used the below powershell for removing all lines except those containing a certain string, but how would I do it for, say 50 strings.
$SourceFile = 'C:\PATH\TO\FILE.csv'
$Pattern = 'word||'
(Get-Content $SourceFile) | % {if ($_ -match $Pattern){$_}} | Set-Content $SourceFile
I guess $Match should be $Pattern in your example.
You can specify multiple keywords in your pattern, like this:
$SourceFile = 'C:\PATH\TO\FILE.csv'
$Pattern = 'word|excel|powerpoint'
(Get-Content $SourceFile) | Where-Object { $_ -match $Pattern } | Set-Content $SourceFile

Powershell replace adding an empty line

I have this powershell code which should replace every occurrence of a string in every file in the directory with a new string.
This works, however an empty line is added in the end.
What causes this, and how can this be nicely avoided?
$files = Get-ChildItem $currentDir *.* -recurse
foreach ($file in $files)
{
$find = "placeholder"
$replace = "newvalue"
$content = Get-Content $($file.FullName) -Raw
$content -replace $find,$replace | Out-File $($file.FullName)
}
Simply removing the last line is not a good solution since sometimes my files will contain an empty line which I want to keep.
You could use the -NoNewline parameter to prevent Out-File from appending the extra line at the end of the file.
$content -replace $find,$replace | Out-File $($file.FullName) -NoNewline
Note: this was added in PowerShell 5.0
I am limited to PS version 4, and this is what I used
$files = Get-ChildItem $currentDir . -recurse
$find = "placeholder"
$replace = ""newvalue"
foreach ($file in $files)
{
$content = Get-Content $($file.FullName) -Raw | ForEach-Object { $_ -replace $find,$replace}
$content = $content -join "`r`n"
$content | Set-Content $($file.FullName)
}
Note that this only works if it is ok to store the complete file in memory.

Powershell: addin line into the .txt file

I have a text (.txt) file with following content:
Car1
Car2
Car3
Car4
Car5
For changing Car1 for random text I used this script:
Get-ChildItem "C:\Users\boris.magdic\Desktop\q" -Filter *.TXT |
Foreach-Object{
$content = Get-Content $_.FullName
$content | ForEach-Object { $_ -replace "Car1", "random_text" } | Set-Content $_.FullName
}
This is working ok, but now I want to add one text line under Car2 in my text file.
How can I do that?
Just chain another -replace and use a new line!
Get-ChildItem "C:\Users\boris.magdic\Desktop\q" -Filter *.TXT |
Foreach-Object{
$file = $_.FullName
$content = Get-Content $file
$content | ForEach-Object { $_ -replace "Car1", "random_text" -replace "(Car2)","`$1`r`nOtherText" } | Set-Content $file
}
First thing is that | Set-Content $_.FullName would not work since the file object does not exist in that pipe. So one simple this to do it save the variable for use later in the pipe. You can also use the ForEach($file in (Get-ChildItem....)) construct.
The specific change to get what you want is the second -replace. We place what you want to match in brackets to that we can reference it in the replacement string with $1. We use a backtick to ensure PowerShell does not treat it as a variable.
We can remove some redundancy as well since -replace will work against the strings of file as a whole
Get-ChildItem "c:\temp" -Filter *.TXT |
Foreach-Object{
$file = $_.FullName
(Get-Content $file) -replace "Car1", "random_text" -replace "(Car2)","`$1`r`nOtherText" | Set-Content $file
}
While this does work with your sample text I want to point out that more complicated strings might require more finesse to ensure you make the correct changed and that the replacements we are using are regex based and do not need to be for this specific example.
.Replace()
So if you were just doing simple replacements then we can update your original logic.
Foreach-Object{
$file = $_.FullName
$content = Get-Content $_.FullName
$content | ForEach-Object { $_.replace("Car1", "random_text").replace("Car2","Car2`r`nOtherText")} | Set-Content $file
}
So that is just simple text replacement chained using the string method .Replace()