powershell 替换和删除
powershell replace and delete
我需要使用标记 ====-
查找字符串 1234
的代码,然后将 ####
替换为 1234
,然后删除行 ====-1234
.
文本文件可以有一组(示例文本 A):
A;1;1;####;19/01/2015;08:45:58;UNKNOWN;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
====-1234
或多个组(示例文本 B):
A;1;1;####;19/01/2015;08:45:58;UNKNOWN;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
====-1234
A;1;1;####;19/01/2015;08:45:58;UNKNOWN;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
====-5678
目前的代码删除了文本文件中的所有内容。有什么帮助吗?
$regex =
@'
(?ms)(.+?####;
.+?)
====-(\d+)
'@
Get-Childitem -Path C:\somedir -Filter *.txt |
foreach {
$text = Get-Content $_
([regex]::matches($text,$regex) |
foreach {
$_.groups[1].value -replace '####',($_.groups[2].value)
}) -join '' |
Set-Content $_.FullName
}
在这种情况下,您可能会受益于使用 ArrayList
。以下方法遍历文件并记录遇到 ####
或 ====-
时的位置。
然后可以修改那些位置的内容,首先直接替换找到####
的索引处的内容,其次使用ArrayList
的removeAt
方法删除遇到 ====-
的条目:
[System.Collections.Arraylist]$t = Get-Content .\sampleb.txt
$removeAt = @()
$i = 0
while($i -lt $t.count) {
if($t[$i] -match "####") {
$start = $i
}
if($t[$i] -match "====-(\d+)") {
$newval = $t[$start] -replace "####", $matches[1]
$t[$start] = $newval
$removeAt += $i
$start = $i
}
$i += 1
}
foreach($idx in ($removeAt | Sort-Object -Descending)) {
$t.removeAt($idx)
}
$t
产出
A;1;1;1234;19/01/2015;08:45:58;UNKNOWN;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
A;1;1;5678;19/01/2015;08:45:58;UNKNOWN;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
这确实假设您的文件是一致的,并且 ====-
总是 遵循 ####
并且两者是平衡的。否则需要额外的逻辑来解释这一点。
这似乎是我之前回答过的一个问题的延续,但该解决方案依赖于使用 Get-Content 的 -Raw 参数,而您显然是 运行 V2。除此之外,发布的数据已从原始问题更改,因此该解决方案无论如何都行不通。
这是一个更新版本,针对新的数据标准进行了调整并与 V2 兼容:
$regex =
@'
(?ms)(.+?####;.+?
.+?)
====-(\d+)
'@
$Files =
Get-Childitem -Path C:\somedir -Filter *.txt
foreach ($file in $files)
{
$Text = Get-Content $file.fullname | out-string
([regex]::matches($text,$regex) |
foreach {
$_.groups[1].value -replace '####',($_.groups[2].value)
}) -join '' |
Set-Content $file.fullname
}
我需要使用标记 ====-
查找字符串 1234
的代码,然后将 ####
替换为 1234
,然后删除行 ====-1234
.
文本文件可以有一组(示例文本 A):
A;1;1;####;19/01/2015;08:45:58;UNKNOWN;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
====-1234
或多个组(示例文本 B):
A;1;1;####;19/01/2015;08:45:58;UNKNOWN;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
====-1234
A;1;1;####;19/01/2015;08:45:58;UNKNOWN;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
====-5678
目前的代码删除了文本文件中的所有内容。有什么帮助吗?
$regex =
@'
(?ms)(.+?####;
.+?)
====-(\d+)
'@
Get-Childitem -Path C:\somedir -Filter *.txt |
foreach {
$text = Get-Content $_
([regex]::matches($text,$regex) |
foreach {
$_.groups[1].value -replace '####',($_.groups[2].value)
}) -join '' |
Set-Content $_.FullName
}
在这种情况下,您可能会受益于使用 ArrayList
。以下方法遍历文件并记录遇到 ####
或 ====-
时的位置。
然后可以修改那些位置的内容,首先直接替换找到####
的索引处的内容,其次使用ArrayList
的removeAt
方法删除遇到 ====-
的条目:
[System.Collections.Arraylist]$t = Get-Content .\sampleb.txt
$removeAt = @()
$i = 0
while($i -lt $t.count) {
if($t[$i] -match "####") {
$start = $i
}
if($t[$i] -match "====-(\d+)") {
$newval = $t[$start] -replace "####", $matches[1]
$t[$start] = $newval
$removeAt += $i
$start = $i
}
$i += 1
}
foreach($idx in ($removeAt | Sort-Object -Descending)) {
$t.removeAt($idx)
}
$t
产出
A;1;1;1234;19/01/2015;08:45:58;UNKNOWN;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
A;1;1;5678;19/01/2015;08:45:58;UNKNOWN;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
这确实假设您的文件是一致的,并且 ====-
总是 遵循 ####
并且两者是平衡的。否则需要额外的逻辑来解释这一点。
这似乎是我之前回答过的一个问题的延续,但该解决方案依赖于使用 Get-Content 的 -Raw 参数,而您显然是 运行 V2。除此之外,发布的数据已从原始问题更改,因此该解决方案无论如何都行不通。
这是一个更新版本,针对新的数据标准进行了调整并与 V2 兼容:
$regex =
@'
(?ms)(.+?####;.+?
.+?)
====-(\d+)
'@
$Files =
Get-Childitem -Path C:\somedir -Filter *.txt
foreach ($file in $files)
{
$Text = Get-Content $file.fullname | out-string
([regex]::matches($text,$regex) |
foreach {
$_.groups[1].value -replace '####',($_.groups[2].value)
}) -join '' |
Set-Content $file.fullname
}