Powershell Foreach 构造删除多个文件中的文本
Powershell Foreach construction remove text in multiple files
作为 powershell 的新手,我在 google 上搜索了很长时间,以制作一个可以根据像这样的变量删除单个文件中的部分文本的作品。文本部分可以位于文件中的任何位置。并且需要删除该特定部分。
<#
#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"
现在我想使用上述工作功能,但要针对特定文件夹中的所有文件。但是,由于 “表达式只允许作为管道的第一个元素。” 我无法使用下面的这段代码:
$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
}
预期结果是文件夹中的所有文件都删除了文本文件的中间部分。
有人可以协助解决这个 foreach 构造问题吗?
我建议您在这个用例中使用 switch
,如果我理解正确的话,您希望开始跳过文件中与 [=13= 的值匹配的行] 并在该行与 $EndText
的值匹配后停止跳过。如果是这种情况,这里是一个最小的示例,说明如何使用带有 -Regex
参数的 switch
语句来执行此操作:
$StartText = '50'
$EndText = '75'
$skip = $false
switch -Regex (0..100) {
$StartText { $skip = $true; continue }
$EndText { $skip = $false; continue }
{ $skip } { continue }
default { $_ }
}
如果这是您所期望的,那么如果您希望每个文件都相同,代码将如下所示,注意使用 -File
来读取每个文件内容:
$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)
}
作为 powershell 的新手,我在 google 上搜索了很长时间,以制作一个可以根据像这样的变量删除单个文件中的部分文本的作品。文本部分可以位于文件中的任何位置。并且需要删除该特定部分。
<#
#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"
现在我想使用上述工作功能,但要针对特定文件夹中的所有文件。但是,由于 “表达式只允许作为管道的第一个元素。” 我无法使用下面的这段代码:
$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
}
预期结果是文件夹中的所有文件都删除了文本文件的中间部分。
有人可以协助解决这个 foreach 构造问题吗?
我建议您在这个用例中使用 switch
,如果我理解正确的话,您希望开始跳过文件中与 [=13= 的值匹配的行] 并在该行与 $EndText
的值匹配后停止跳过。如果是这种情况,这里是一个最小的示例,说明如何使用带有 -Regex
参数的 switch
语句来执行此操作:
$StartText = '50'
$EndText = '75'
$skip = $false
switch -Regex (0..100) {
$StartText { $skip = $true; continue }
$EndText { $skip = $false; continue }
{ $skip } { continue }
default { $_ }
}
如果这是您所期望的,那么如果您希望每个文件都相同,代码将如下所示,注意使用 -File
来读取每个文件内容:
$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)
}