I am trying to create a powershell script which looks through all files and folders under a given directory it then changes all instances of a given word in .properties file
Simplified contains clause
$file = Get-Content $_.FullName
if ((Get-Content $file | %{$_ -match $wordToFind}) -contains $true) {
Add-Content log.txt $_.FullName
($file) | ForEach-Object { $_ -replace $wordToFind , $wordToReplace } |
Set-Content $_.FullName
}
Try this:
$directoryToTarget=$args[0]
$wordToFind=$args[1]
$wordToReplace=$args[2]
Clear-Content log.txt
Get-ChildItem -Path $directoryToTarget -Filter *.properties -Recurse | where { !$_.PSIsContainer } | % {
$file = Get-Content $_.FullName
$containsWord = $file | %{$_ -match $wordToFind}
If($containsWord -contains $true)
{
Add-Content log.txt $_.FullName
($file) | ForEach-Object { $_ -replace $wordToFind , $wordToReplace } |
Set-Content $_.FullName
}
}
This will put the content of the file into an array $file
then check each line for the word. Each lines result ($true
/$false
) is put into an array $containsWord
. The array is then check to see if the word was found ($True
variable present); if so then the if loop
is run.
The simplest way to check that file contains the word
If we are looking at Get-Content
result we find string System.Array. So, we can do like in System.Linq in .NET:
content.Any(s => s.Contains(wordToFind));
In PowerShell it looks like:
Get-Content $filePath `
| %{ $res = $false } `
{ $res = $res -or $_.Contains($wordToFind) } `
{ return $res }
As a result, we can aggregate it in cmdlet with params of file path and containing word and use it. And one more: we can use Regex with -match
instead of Contains
, so it will be more flexible.