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.
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
Windows 10 64 BIT
Scenario: copy files in a directory and subdirectory to the destination directory.
File Type: Only pdf
Issue: When the file name has special characters not able to copy
Tried below code not working
#Get all files and not the directories
$files = Get-ChildItem -Path "c:/source" -Recurse -filter "*.pdf" | Where {$_.PSIsContainer -eq $false}
#Copy items from sources to new destination
foreach ($file in $files)
{
if ($file.Name -match '[^a-zA-Z0-9]')
{
$file.FullName
*$file.FullName | Rename-Item -NewName {$_ -replace '_*(\[.*?\]|\(.*?\))_*' -replace '_+', ' '} $NewName
*Rename-Item -NewName {$_ -replace '_*(\[.*?\]|\(.*?\))_*' -replace '_+', ' '}
*$NewName = rename-item $file.FullName.Replace('_*(\[*?\]|\(*?\))_*', '')
Rename-Item -Path $file.fullName -NewName {$_ -replace '_*(\[.*?\]|\(.*?\))_*' -replace '_+', ' '}
}
Copy-Item -Path $file.FullName -Destination "c:/desination\"
}
I'm new to Power-Shell.
Given a text file with multiple file paths each separated by a New Line, I'm trying to replace the file path of each of these with a new path for the same file.
Example:
Input file :
C:\Project\SharedLib\Shared\log4net.dll
C:\Project\SharedLib\Shared\Aspose.dll
C:\Dependency\SL\UnStable\Crystal.dll
Output file :
\\ServerName\websites$\Stable\Release\log4net.dll
\\ServerName\websites$\Stable\Release\Aspone.dll
\\ServerName\websites$\Stable\Release\Crystal.dll
My attempt:
Get-ChildItem "*.txt" -Filter *.txt |
Foreach-Object {
foreach($line in Get-Content $_) {
$currentPath = [System.IO.Path]::GetDirectoryName($line)
($line) -replace $currentPath, '\\ServerName\websites$\Stable\Release\' | Set-Content $line
}
}
This is erring on the replace line.
this uses Split-Path to get the file name. then it uses Join-Path to build the new full path. [grin]
$SourceFile = "$env:TEMP\Reddy-In.txt"
$DestFile = "$env:TEMP\Reddy-Out.txt"
# create a file to work with
# remove this section when ready to use your own data
#'
C:\Project\SharedLib\Shared\log4net.dll
C:\Project\SharedLib\Shared\Aspose.dll
C:\Dependency\SL\UnStable\Crystal.dll
'# | Set-Content -LiteralPath $SourceFile
$Prefix = '\\ServerName\websites$\Stable\Release'
$InStuff = Get-Content -LiteralPath $SourceFile
$Results = foreach ($IS_Item in $InStuff)
{
$FileName = Split-Path -Path $IS_Item -Leaf
Join-Path -Path $Prefix -ChildPath $FileName
}
# display on screen
$Results
# send to a text file
$Results |
Set-Content -LiteralPath $DestFile
screen output ...
\\ServerName\websites$\Stable\Release\log4net.dll
\\ServerName\websites$\Stable\Release\Aspose.dll
\\ServerName\websites$\Stable\Release\Crystal.dll
text file content ...
\\ServerName\websites$\Stable\Release\log4net.dll
\\ServerName\websites$\Stable\Release\Aspose.dll
\\ServerName\websites$\Stable\Release\Crystal.dll
The error message I was getting was
The regular expression pattern C:\Project\SharedLib\Shared is not valid.
At C:\temp\StackOverflow.ps1:6 char:9
+ ($line) -replace $currentPath, '\\ServerName\websites$\Stable ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (C:\Project\SharedLib\Shared:String) [], RuntimeException
+ FullyQualifiedErrorId : InvalidRegularExpression
This tells me that the string C:\Project\SharedLib is being treated as a RegEx pattern- and we need to escape the operators. (That's why you'll often see backslashes doubled up- they are escaped.)
No need to remember what they are all- you can use [regex]::escape($currentPath) to do it for you.
Get-ChildItem "*.txt" -Filter *.txt |
Foreach-Object {
foreach($line in Get-Content $_) {
$currentPath = [System.IO.Path]::GetDirectoryName($line)
($line) -replace [regex]::escape($currentPath), '\\ServerName\websites$\Stable\Release\' | Set-Content $line
}
}
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
}
}
}
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
}