0

I am trying to replace multiple strings in all files within a folder. The problem is that -replace operator does not take into account the exact words that I need to replace for example:

I need to replace strings:

  1. RUN → Run
  2. RUNMODAL → RunModal

Now when I run my script it replaces the RUN strings into Run which is good, but it replaces also RUNMODAL into RunMODAL and it does not take into account my second condition. Is there any way to specify that only exact matches should be taken into account or at least for each replace I'd specify the number of characters to be taken into consideration when replacing a particular string?

$AllFiles = Get-ChildItem $FilePath

foreach ($file in $AllFiles) {
    (Get-Content $file.PSPath) | ForEach {
        $_ -creplace 'RUN', 'Run' `
           -creplace 'RUNMODAL', 'RunModal'
    } | Set-Content  $file.PSPath
}

Edit:

Maybe a better example would be:

  1. FIELD → field
  2. NEWFIELD → NewField

Even if I switch these to I would either get NEWfield or Newfield and I need NewField.

3 Answers 3

1

Use word boundaries (\b) in your search strings to ensure that you're replacing only complete words. And you don't need a nested loop. The replacement operators can be used directly on lists.

Get-ChildItem $FilePath | ForEach-Object {
    (Get-Content $_.FullName) -creplace '\bRUN\b', 'Run' `
            -creplace '\bRUNMODAL\b', 'RunModal' `
            -creplace '\bFIELD\b', 'NewField' |
        Set-Content  $_.FullName
}
Sign up to request clarification or add additional context in comments.

Comments

0
$AllFiles = Get-ChildItem $FilePath

(Get-Content $file.PSPath) |
ForEach {
       $_ -creplace 'RUNMODAL', 'RunModal' `
          -creplace 'RUN', 'Run'
} | Set-Content  $file.PSPath

1 Comment

Unfortunately it is not that simple. In this case it'd work, but I have around 30 conditions to be met and I need this script to be working not like that, but it'd need to replace only exact words. I've got also examples like FIELD > field and NEWFIELD > NewField and in this case it won't work because it either replaces it to Newfield or it leaves it as NEWfield because the script is case-sensitive.
0

I did find also another solution which is:

foreach ($file in $AllFiles) 
{
    (Get-Content $file.PSPath) | ForEach-Object {
        $line = $_

        $lookupTable.GetEnumerator() | ForEach-Object {
            if ($line -like $_.Key)
            {
                $line = $line -replace $_.Key, $_.Value
            }
        }
       $line
    } | Set-Content $file.PSPath
}

I will try yours as well. Thanks!

2 Comments

Getting your search and replace strings from a hashtable doesn't help with replacing entire words only. Also, there is no effective difference between a condition $line -like $_.Key and $line -eq $_.Key unless $_.Key contains wildcard characters, which would make it unsuitable as a search string for a regular expression replacement.
Yeap, after few tests I also found this not to be the best solution. Anyway I've used the version with \bXXXz\b and it works almost perfect.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.