0
votes

I need to create a script for a user that will find all .txt files in a selected directory, look for a specific string in each of them, add a carriage return at the start of this specific string, and then output the edited .txt files into a directory that is one above the initial selected directory.

Preferably, it should be able to run without admin privileges.

To be clear, they desire an effect that would change the .txt file from this:

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas fringilla neque finibus velit condimentum, sed feugiat diam iaculis. In hac habitasse platea dictumst. TEXT STRING Vestibulum fringilla dui nec diam convallis, et cursus elit finibus. Vivamus porttitor est ac erat gravida pellentesque. Cras rhoncus urna a dui hendrerit auctor. Suspendisse potenti TEXT STRING. Interdum et malesuada fames ac ante ipsum primis in faucibus.

To this:

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas fringilla neque finibus velit condimentum, sed feugiat diam iaculis. In hac habitasse platea dictumst.
TEXT STRING Vestibulum fringilla dui nec diam convallis, et cursus elit finibus. Vivamus porttitor est ac erat gravida pellentesque. Cras rhoncus urna a dui hendrerit auctor. Suspendisse potenti
TEXT STRING. Interdum et malesuada fames ac ante ipsum primis in faucibus.


This is what I have come up with so far, and it stops working at the Get-Content line:

Function Get-Folder()
{
Add-Type -AssemblyName System.Windows.Forms

$FolderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog -Property @{
    RootFolder = 'MyComputer'
    ShowNewFolderButton = $true
}

[void]$FolderBrowser.ShowDialog()
$FolderBrowser.SelectedPath
}

$inputFolder=Get-Folder

foreach($file in Get-ChildItem -name $inputFolder\*.txt){

(Get-Content $file ).Replace("text","`r`n text") | Out-File $inputFolder\..\output\$_

}

pause

This is the error it throws when this script is run:

Get-Content : Cannot find path 'C:\powershell\testing.txt' because it does not exist. At C:\powershell\test_script_02.ps1:22 char:2 + (Get-Content $file ).Replace("text","rn text") | Out-File $inputFol ... + ~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (C:\powershell\testing.txt:String) [Get-Content], ItemNotFoundException + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand

You cannot call a method on a null-valued expression. At C:\powershell\test_script_02.ps1:22 char:1 + (Get-Content $file ).Replace("text","rn text") | Out-File $inputFol ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull

Get-Content : Cannot find path 'C:\powershell\testing0.txt' because it does not exist. At C:\powershell\test_script_02.ps1:22 char:2 + (Get-Content $file ).Replace("text","rn text") | Out-File $inputFol ... + ~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (C:\powershell\testing0.txt:String) [Get-Content], ItemNotFoundException + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand

You cannot call a method on a null-valued expression. At C:\powershell\test_script_02.ps1:22 char:1 + (Get-Content $file ).Replace("text","rn text") | Out-File $inputFol ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull

It fails to find each text file in the path, which I know to exist. When the Get-Content line is commented out and replaced with a Write-Host command, the script correctly prints every file in the directory. I'm not sure how it seems to be failing to find the correct files.

I know that there must be better ways to do this, I'm very new to Powershell and this is just what I've cobbled together from web searching around. Any help is greatly appreciated.

4
What have you tried, and how has what you've tried failed? Ideally, you should provide a minimal reproducible example of what you've tried, and include specific information on how it failed, with error messages and/or erroneous output. Stack Overflow is not a code-writing service; the best questions are those which provide useful information so that those who answer can guide you to devising your own correct answer. See How to Ask a Good Question. - Jeff Zeitlin
Is there a reason why you need a dialog window? Could your user do this with just command line arguments? - HeedfulCrayon
Is your script not working, or do you just want someone to improve it somehow? - HeedfulCrayon
Question edited to add the errors I receive. The dialog window was at the request of the user. The script does not work as-is at all. - user9492893

4 Answers

0
votes

Use Get-Content $file.FullName to refer to the full path of the file rather than just its name relative to the current location:

(Get-Content $file.FullName).Replace("text","`r`n text") | Out-File $inputFolder\..\output\$($file.Name)
0
votes

Your Function isn't returning the string value you expect. put the $folderbrowser.selectedpath in ()

Function Get-Folder()
{
Add-Type -AssemblyName System.Windows.Forms

$FolderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog -Property @{
    RootFolder = 'MyComputer'
    ShowNewFolderButton = $true
}

[void]$FolderBrowser.ShowDialog()
($FolderBrowser.SelectedPath)
}
0
votes

For your Get-Folder function you need to use the return keyword to return the selected folder. Also in your foreach loop, you need to indicate -path to the input folder, and use the switch -include with the type of extension you are looking for.

Function Get-Folder()
{
    Add-Type -AssemblyName System.Windows.Forms

    $FolderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog -Property @{
        RootFolder = 'MyComputer'
        ShowNewFolderButton = $true
    }

    [void]$FolderBrowser.ShowDialog()
    return $FolderBrowser.SelectedPath
}

$inputFolder=Get-Folder

foreach($file in Get-ChildItem -path $inputFolder -include *.txt){

    (Get-Content $file.FullName ).Replace("text","`r`n text") | 
        Out-File -filePath $inputFolder\..\output\$file.Name

}
0
votes

to get the replacement done you would have to do something like this

$path = "Pathtofile"
(get-content $path -Raw) -replace "(TEXT STRING)","`r`n`$1"|
  out-file ($path -replace '\.txt','_reworked.txt')

when using -replace you can capture the match through () and refer to it in the replacementstring by using $1, but since that string Needs to be in double quotes for the linebreak to work you Need to escape the $ so powershell does not replace $1 with $null in this Case.