I have written the below conditional script to go through the files in the directory and replace the one text in all files only if file contains the word as 'Health'
cd -Path "\\shlhfilprd08\Direct Credits\Temp2"
ForEach ($file in (Get-ChildItem -Path "\\shlhfilprd08\Direct Credits\Temp2"))
{
$filecontent = Get-Content -path $file -First 1
if($filecontent -like '*Health*'){$filecontent = $filecontent -replace 'TEACHERF','UniHlth '}
Set-Content $file.PSpath -Value $filecontent
}
I come across with two issues such as
If the ($filecontent -like 'Health'), it is replacing the word in first raw and deleting other rows along with replace.I do not want that to happen
I'm getting set-content to path is denied error message for file content does not contain the Health text
Can you try with this
cd -Path "\\shlhfilprd08\Direct Credits\Temp2"
$configFiles = Get-ChildItem . *.config -rec
foreach ($file in $configFiles)
{
(Get-Content $file.PSPath) |
Foreach-Object { $_ -replace "TEACHERF", "UniHlth " } |
Set-Content $file.PSPath
}
I would try this; it worked for me in a little file
(make a small copy of a few data into a new folder and test it there)
$path = "\\shlhfilprd08\Direct Credits\Temp2"
$replace ="TEACHERF" #word to be replaced
$by = "UniHlth " #by this word (change $replace by $by)
gci $path -file | %{
foreach($line in $(Get-content $_.Fullname)){
if($line -like $replace){
$newline = $line.Replace($($replace),$($by))
Set-Content $_.FullName $newline
}
}
}
Related
I have multiple files. Let's name them File1, File2, File3 and so on.
Each files has multiple lines in the format:
Some text,some more text,more text
I need to do the following:
In each line of each file, remove the first part of the text before the ",".
So "Some text,some more text,more text" should become "some more text,more text"
Prefix the respective file name to each line with a comma :
"some more text,more text" - becomes "File1,some more text,more text"
I checked out a similar request here : Powershell - Delete Everything After a Delimiter - In Text files Found in Folder
But still unable to get things rolling. This is what I tried for the first part of the request:
Foreach ($file in (Get-Childitem $path))
{
(Get-Content $file.fullname -Delimiter ',')[1] |
Set-Content "$OutPath\$($file.name)"
}
This removes the text before the first "," and after the second "," - I need to keep all text after the first ",".
Another approach could be to use regex and the -replace operator:
Foreach ($file in (Get-Childitem $path)) {
$Content = Get-Content -Path $file.fullname
$NewContent =
foreach ($line in $Content) {
$line -replace '^.*?(?=,)', $file.BaseName
}
$NewContent | Out-File -FilePath "$OutPath\$($file.name)"
}
Use the -split operator, on which you can specify how many parts you want in the result.
Something like this:
$Path = 'D:\Original' # the path where the original files are
$OutPath = 'D:\Updated' # the path where the updated files should go
# check if the output path exists. If not, create it
if (!(Test-Path -Path $OutPath -PathType Container)) {
$null = New-Item -Path $OutPath -ItemType Directory
}
foreach ($file in (Get-Childitem -Path $path -File)) {
(Get-Content $file.FullName) | ForEach-Object {
# the $_ automatic variable represents one line for each iteration.
# output the updated line. The cleanest way I think is to use the -f Format operator.
# https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_operators?view=powershell-5.1#format-operator--f
'{0},{1}' -f $file.Name, ($_ -split ',', 2)[-1]
} |
Set-Content -Path (Join-Path -Path $OutPath -ChildPath $file.Name)
}
Hope that helps
in particular path i need to find ""' and replace it with "' in multiple files
Tried below code but its not working due to special character to be found and replaced
$configFiles = Get-ChildItem . *.ini -rec
foreach ($file in $configFiles)
{
(Get-Content $file.PSPath) |
Foreach-Object { $_ -replace """'", ""'" } |
Set-Content $file.PSPath
}
You're not escaping your characters properly:
$configFiles = Get-ChildItem -Filter *.ini -Recurse
ForEach ($file in $configFiles)
{
#(Get-Content -Path $file.FullName) -replace "`"{2}'", "`"'" |
Set-Content -Path $file.FullName
}
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.
I have this piece of code that changes a string if it exist. It works perfectly. However, even if the Server1 string doesn't exist in the file it changes the modified date of the file. What I need it to do is if the string Server1 doesn't exist ignore and move on to the remaining files in the folder.
Does anyone here know how I can go about achieving this?
$filenames = Get-ChildItem "C:\test\*.dtsconfig" -Recurse |
select -Expand FullName
foreach ($filename in $filenames) {
(Get-Content $filename) -replace 'Server1', 'Server2' | Set-Content $filename
}
Write the file only if it actually contains the string "Server1":
$txt = Get-Content $filename
if ($txt -like '*Server1*') {
$txt -replace 'Server1', 'Server2' | Set-Content $filename
}
$fileNames = Get-ChildItem "C:\test\*.dtsconfig" -Recurse | Select -Expand FullName
foreach ($filename in $filenames) {
$file = Get-Content $fileName
If ($file -like "*Server1*") {
Get-Content $fileName -replace 'Server1', 'Server2' | Set-Content $fileName
}
}
I've added in an if statement so it checks before making any changes.
I'm working on a script to format a directory full of text files and export them to CSV files. I want it to perform the search and replace on each file to format it properly, export it to a CSV with the same filename, then move to the next txt file. I have the search and replace working, but can't work out how to save each text file with its original filename. What am I doing wrong?
$path = "H:\My Documents\EmailSaveAs\"
$files = Get-ChildItem -Path $path -include *.txt -recurse
echo $files
foreach($file in $files) {
Foreach-Object {
$_ -replace "`r`n`t", "," -replace "\s`r`n", "," -replace "Bytes `r`nOut", "Bytes Out" -replace "`t", "," -replace "Idle-`r`ntimeout", "Idle-timeout" -replace ",#Date", "#Date"
} |
Set-Content $path $(.BaseName + ".csv")
}
Try this:
$path = "H:\My Documents\EmailSaveAs\"
$files = Get-ChildItem $path -include *.txt -recurse
echo $files
foreach($file in $files) {
$updatedContent = Get-Content $file.FullName -Raw | Foreach-Object {
$_ -replace "`r`n`t", "," -replace "\s`r`n", "," -replace "Bytes `r`nOut", "Bytes Out" -replace "`t", "," -replace "Idle-`r`ntimeout", "Idle-timeout" -replace ",#Date", "#Date"
}
$newFilename = [io.path]::ChangeExtension($file, ".csv")
Set-Content $newFilename $updatedContent
}
Your original code was accessing $_ when it wasn't executing in a pipeline context. Note that the -Raw parameter on Get-Content is new in V3.