I'm trying to do a replace in content of all files in a certain directory structure.
get-childItem temp\*.* -recurse |
get-content |
foreach-object {$_.replace($stringToFind1, $stringToPlace1)} |
set-content [original filename]
Can I get the filename from the original get-childItem to use it in the set-content?
Add processing for each file:
get-childItem *.* -recurse | % `
{
$filepath = $_.FullName;
(get-content $filepath) |
% { $_ -replace $stringToFind1, $stringToPlace1 } |
set-content $filepath -Force
}
Key points:
$filepath = $_.FullName; — get path to file
(get-content $filepath) — get content and close file
set-content $filepath -Force — save modified content
You can simply use $_, but you need a foreach-object around each file, too. While #akim's answer will work, the use of $filepath is unnecessary:
gci temp\*.* -recurse | foreach-object { (Get-Content $_) | ForEach-Object { $_ -replace $stringToFind1, $stringToPlace1 } | Set-Content $_ }
Related
I have many folder
ex: folder1,folder2,folder3... about folder100
In those folder have many files
ex: 1.html,2.html,3.html,4.html...about 20.html
I want to replace some text in those all html file in all folder
but not all text i want to replace is same.
ex:(for 1.html, i want to replace ./1_files/style.css to style.css) and (for 2.html, i want to replace ./2_files/style.css to style.css)....
So i try something like this and it work well
Get-ChildItem "*\1.html" -Recurse | ForEach-Object -Process {
(Get-Content $_) -Replace './1_files/style.css', 'style.css' | Set-Content $_
}
Get-ChildItem "*\2.html" -Recurse | ForEach-Object -Process {
(Get-Content $_) -Replace './2_files/style.css', 'style.css' | Set-Content $_
}
Get-ChildItem "*\3.html" -Recurse | ForEach-Object -Process {
(Get-Content $_) -Replace './3_files/style.css', 'style.css' | Set-Content $_
}
Get-ChildItem "*\4.html" -Recurse | ForEach-Object -Process {
(Get-Content $_) -Replace './4_files/style.css', 'style.css' | Set-Content $_
}
but i have to write many of those code "\4.html" "\5.html" "*\6.html" ...
i try this but it do not work
Do {
$val++
Write-Host $val
$Fn = "$val.html"
Get-ChildItem "*\$Fn" -Recurse | ForEach-Object -Process {
(Get-Content $_) -Replace './$val_files/style.css', 'style.css' |
Set-Content $_
}
} while($val -ne 100)
Please show me correct way to do..loop replace
thanks you
Assuming all your subfolders can be found inside one source folder path, you can do below to do the replacement in all those files:
# the path where all subfolders and html files can be found
$sourcePath = 'X:\Wherever\Your\Subfolders\Are\That\Contain\The\Html\Files'
Get-ChildItem -Path $sourcePath -Filter '*.html' -Recurse -File |
# filter on html files that have a numeric basename
Where-Object {$_.BaseName -match '(\d+)'} | ForEach-Object {
# construct the string to repace and escape the regex special characters
$replace = [regex]::Escape(('./{0}_files/style.css' -f $matches[1]))
# get the content as one single multiline string so -replace works faster
(Get-Content -Path $_.FullName -Raw) -replace $replace, 'style.css' |
Set-Content -Path $_.FullName
}
I'm looking to replace the character 'a' with 'o' in all txt files in a directory: "D:\Aither\Pca\Stat\"
For now I use this, but lose time because there are a lot of files.
(Get-Content D:\Aither\Pca\Stat\StrEtb.dat).replace('a', 'o') | Set-Content D:\Aither\Pca\Stat\StrEtb.dat
(Get-Content D:\Aither\Pca\Stat\StrEtb2.dat).replace('a', 'o') | Set-Content D:\Aither\Pca\Stat\StrEtb2.dat
....
I want something like this:
(Get-Content D:\Aither\Pca\Stat\*).replace('a', 'o') | Set-Content D:\Aither\Pca\Stat\*
Is this possible in PowerShell?
Using the -Filter and -File parameters, you will have better performance in collecting the files. Also, you can use a ForEach-Object to simply pipe these files through to the next cmdlet.
Because you are overwriting the file(s), you need to use brackets around Get-Content, so you are not trying to read and write to the same file at the same time.
Get-ChildItem -Path 'D:\Aither\Pca\Stat' -Filter '*.dat' -File -Recurse | ForEach-Object {
($_ | Get-Content).Replace('a', 'o') | Set-Content $_.FullName
}
Try this:
$collection = Get-ChildItem -Path 'D:\Aither\Pca\Stat' -Recurse -Filter '*.dat'
foreach( $file in $collection ) {
(Get-Content $file.FullName).replace('a', 'o') | Set-Content ($file.FullName) | Out-Null
}
I have a PowerShell script that I want to run to add two lines 'IM_DISABLED' & 'IM_NO_SETUP=1' to the end of each INI file.
I want to run it against a folder H:\test which has subfolders each containing a file notes.ini.
I have the following PowerShell which works using -replace. However, I'm unable to use replace and need to just append two new lines to the end of each INI.
$places = 'h:\test'
$places | Get-ChildItem -Recurse -Include Notes.ini | ForEach-Object {
(Get-Content $_) -replace 'KitType=1', "`nKitType=1`r`nIM_DISABLED=1`r`nIM_NO_SETUP=1" |
Set-Content $_
'Processed: {0}' -f $_.FullName
}
If you have PowerShell v3 or newer you can simply use Add-Content:
$places = 'h:\test'
$lines = 'IM_DISABLED', 'IM_NO_SETUP=1'
Get-ChildItem $places -Recurse -Include Notes.ini | ForEach-Object {
Add-Content $_.FullName -Value $lines
'Processed: {0}' -f $_.FullName
}
On earlier versions you can use Out-File with the parameter -Append. Note that you also need to define the encoding if the file isn't Unicode-encoded.
$places = 'h:\test'
$lines = 'IM_DISABLED', 'IM_NO_SETUP=1'
Get-ChildItem $places -Recurse -Include Notes.ini | ForEach-Object {
Out-File $_.FullName -InputObject $lines -Append -Encoding Ascii
'Processed: {0}' -f $_.FullName
}
Another option is to make an array of Get-Content output and the lines you want to add and write that back to the file with Set-Content:
$places = 'h:\test'
Get-ChildItem $places -Recurse -Include Notes.ini | ForEach-Object {
$f = $_.FullName
(Get-Content $f), 'IM_DISABLED', 'IM_NO_SETUP=1' | Set-Content $f
'Processed: {0}' -f $f
}
I use below code to change strings in files:
Set-Location -Path C:\Users\Documents\corporate
foreach ($file in get-ChildItem *.rdl)
{
$_.Replace("Protection", "Converters") | Set-Content $file
$_.Replace("Drives", "Automation") | Set-Content $file
$_.Replace("MACHINES", "Generators") | Set-Content $file
$file.name
}
I want to add information what has changed in individual files.
For example:
file 1 Protection
file 3 Protection, MACHINES
try this way ...
Get-Content -Path "C:\Users\Documents\corporate" -Filter "*.rdl" | ForEach-Object {
$Local:CurrentFileFullName = $_.FullName
((Get-Content -Path $CurrentFileFullName ) -replace "Protection", "Converters" -replace "Drives", "Automation" -replace "MACHINES", "Generators" | Set-Content $CurrentFileFullName -Force)
}
Newbie stuck doing the basics.
I'm trying to copy files from A to B & then replace text within each file copied. Pretty basic - but it fails What am I doing wrong? Any assistance would be welcome - please. nb I believe I need to use copy-item, alternatives okay as long as same result.
$files = Copy-Item -Path "C:\from" -Filter *.* -Recurse -Destination "C:\to" -Force -PassThru
foreach ($file in $files) {
Get-Item $file |
Where-Object {-not $_.PsIsContainer} |
(Get-Content .) |
Foreach-Object {
$_ -replace ( "maskkey", $maskvalue} |
Set-Content $file
}
}
You need to move the get-content part within the foreach-object script block, and use $_ instead of .
So, something like this:
foreach($file in $files){
Get-Item $file | Where-Object {-not ($_.PsIsContainer)} | Foreach-Object{
$content = Get-Content $_
$newContent = $content.replace("maskkey", $maskvalue)
Set-Content -Value $newContent -Path $file
}
}
Note. I haven't actually tested this code, but you should at least have the basic structure right.