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
}
Related
cd 'A:\P\E\D'
$files = Get-ChildItem . *.CSV -rec
ForEach ($file in $files) {
(Get-Content $file -Raw) | ForEach-Object {
*some simple code*
} | Set-Content $file
}
How to modify this powershell script to locate only files starting with letters A/a to O/o and ending with .csv in specified directory cd?
I thought the solution below would work, but the test file M_K_O_X.CSV stored in the cd directory was not found and modified. The solution above will find and modify the file. It's possible that I have the regex expression wrong or the problem is somewhere else? I tried also this regex -- "[A-O]..CSV"
cd 'A:\P\E\D'
$files = Get-ChildItem . -rec | Where-Object { $_.Name -like "[a-oA-O]*.*.CSV" }
ForEach ($file in $files) {
(Get-Content $file -Raw) | ForEach-Object {
*some simple code*
} | Set-Content $file
}
Looking at your wildcard pattern, seems like you have an extra *. that shouldn't be there:
'M_K_O_X.CSV' -like '[a-oA-O]*.*.CSV' # False
'M_K_O_X.CSV' -like '[a-oA-O]*.CSV' # True
In this case you could simply use the -Include Parameter which supports character ranges. Also PowerShell is case insensitive by default, [a-oA-O]*.CSV can be reduced to [a-o]*.CSV:
Get-ChildItem 'A:\P\E\D' -Recurse -Include '[a-o]*.csv' | ForEach-Object {
($_ | Get-Content -Raw) | ForEach-Object {
# *some simple code*
} | Set-Content -LiteralPath $_.FullName
}
As commented, I would use the standard wildcard -Filter to filter for all files with a .csv extension.
Then pipe to a Where-Object clause in which you can use regex -match
$files = Get-ChildItem -Path 'A:\P\E\D' -Filter '*.csv' -File -Recurse |
Where-Object { $_.Name -match '^[a-o]' }
foreach ($file in $files) {
# switch `-Raw` makes Get-Content return a single multiline string, so no need for a loop
$content = Get-Content -Path $file.FullName -Raw
# *some simple code manipulating $content*
$content | Set-Content -Path $file.FullName
}
However, if these are valid csv files, I would not recommend using a pure textual manipulation on them, instead use Import-Csv -Path $file.FullName and work on the properties on each of the objects returned.
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 have a folder containing multiple text files that I am combining into one file. On that output file I need to add a string to the top and the bottom of the file. I have tried using insert and I keep getting an error. The file is contained in the $Output variable
My code so far:
if(!(Test-Path -Path $PathDump)) {
# create the folder if it does not yet exist
New-Item -ItemType Directory $PathDump
}
# move all *.txt items from 'C:\RemoveFirst\txt' to 'C:\RemoveFirst\DumpARoo'
# EXCEPT the output file itself
$Path = (Get-ChildItem -Path $Path -Filter '*.txt' -File).FullName | Where-Object { $_ -ne $Output}
Move-Item -Path $Path -Destination $PathDump # move (not copy) files into new directory to concat
Get-ChildItem -Path $PathDump -Filter '*.txt' -File | ForEach-Object {
'' # Output an empty line at SOF
'---------------------------------------------------------------'
$_ | Get-Content | Select-Object -Skip 1 | Select-Object -SkipLast 1
'---------------------------------------------------------------'
'' # Output an empty line at EOF
} | Add-Content -Path $OutPut
The story continues ;)
Try this:
$Path = 'C:\RemoveFirst\*.txt'
$PathDump = 'C:\RemoveFirst\DumpARoo'
$Output = 'C:\RemoveFirst\TestingFile.txt'
if(!(Test-Path -Path $PathDump)) {
# create the folder if it does not yet exist
New-Item -ItemType Directory $PathDump
}
# move all *.txt items from 'C:\RemoveFirst\txt' to 'C:\RemoveFirst\DumpARoo'
# EXCEPT the output file itself
$Path = (Get-ChildItem -Path $Path -Filter '*.txt' -File).FullName | Where-Object { $_ -ne $Output}
Move-Item -Path $Path -Destination $PathDump # move (not copy) files into new directory to concat
# Output 'SOF'
"SOF" | Add-Content -Path $OutPut
Get-ChildItem -Path $PathDump -Filter '*.txt' -File | ForEach-Object {
# output the content of the current file
$_ | Get-Content | Select-Object -Skip 1 | Select-Object -SkipLast 1 | Add-Content -Path $OutPut
}
# Output 'EOF'
"EOF" | Add-Content -Path $OutPut
I am grabbing the last line of a file and outputing it in another file with the same name with a "t" prefix but an errors comes up.
$path = 'D:\files\'
$inc = #("*txt_*")
$exc = #("*csv_*")
$List = Get-ChildItem -Path $path -recurse -include $inc -exclude $exc
foreach ($item in $List) {
Get-Content $item.Fullname -Tail 1 | Out-File -Encoding Ascii $path"t-"$item
}
However, if I dont prepend the file name it works fine.
Get-Content $item.Fullname -Tail 1 | Out-File -Encoding Ascii $path"t-"
What is wrong with this?
Prepend the filename with T- and build the destination path from the folder name and the modified filename:
Get-ChildItem -Path $path -Recurse -Include $inc -Exclude $exc | ForEach-Object {
$dst = Join-Path $_.Directory.FullName ($_.Name -replace '^', 'T-')
Get-Content $_.FullName -Tail 1 | Set-Content $dst -Encoding ascii
}
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 $_ }