Reputation: 13
As newby to powershell I googled a long time to make a piece that can remove a part of text in a single file based upon some variables like this. The text section can be anywhere within the file. And that specific section needs to be removed.
<#
#create test file
$file = "c:\users\public\Test\remove.txt"
Set-Content $file (1..100) -Force
$content = Get-Content $file
#>
$file = Get-Content "c:\users\public\Test\remove.txt"
$StartText= '50'
$EndText= "75"
$LineNumberStart= $file | Select-string -Pattern $StartText
$Start = $linenumberStart.LineNumber
$LineNumberEnd= $file | Select-string -Pattern $EndText
$End = $linenumberEnd.LineNumber
$keep = $file[0..$Start] + $file[$End..($file.Count - 1)]
$keep | Set-Content "c:\users\public\test\remove.txt"
Now I would like have to the above working functionality but on all files in a particular folder. However, for the reason "Expressions are only allowed as the first element of a pipeline." I can't get it to work with this piece of code below:
$ReportPath = Split-Path -Parent $Script:MyInvocation.MyCommand.Path
$StartText= "50"
$EndText= "75"
Get-ChildItem -Path $ReportPath -Filter *.txt | ForEach { (Get-Content $_.PSPath) |
$LineNumberStart= $_ | Select-string -Pattern $StartText
$Start = $LineNumberStart.LineNumber
$LineNumberEnd= $_ | Select-string -Pattern $EndText
$End = $LineNumberEnd.LineNumber
$keep = $_[0..$Start] + $_[$End..($_.Count - 1)]
$keep|Set-Content $_.PSPath
}
Expected outcome is that all files in the folder have the middle section of the text file removed.
Can someone please assist in getting this foreach construction resolved?
Upvotes: 1
Views: 193
Reputation: 60120
I would recommend you to use a switch
for this use case, if I understand correctly you're looking to start skipping the lines of a file from where the line matches the value of $StartText
and stop skipping after the line matches the value of $EndText
. If that's the case, here is a minimal example of how you can do this using a switch
statement with the -Regex
parameter:
$StartText = '50'
$EndText = '75'
$skip = $false
switch -Regex (0..100) {
$StartText { $skip = $true; continue }
$EndText { $skip = $false; continue }
{ $skip } { continue }
default { $_ }
}
If this is what you expected, then if you want to the same for each file, the code would look like this, note the use of -File
to read each file content:
$StartText = '50'
$EndText = '75'
$skip = $false
Get-ChildItem -Path $ReportPath -Filter *.txt | ForEach-Object {
& {
switch -Regex -File ($_.FullName) {
$StartText { $skip = $true; continue }
$EndText { $skip = $false; continue }
{ $skip } { continue }
default { $_ }
}
} | Set-Content ($_.BaseName + '-New' + $_.Extension)
}
Upvotes: 1