【发布时间】:2021-03-02 05:45:40
【问题描述】:
Doug 建议跟进我之前关于匿名文件的问题 ( PowerShell - Find and replace multiple patterns to anonymize file) 我需要将所有哈希表值保存在单个文件“tmp.txt”中以供进一步处理。 示例:使用字符串处理输入文件后:
<requestId>>qwerty-qwer12-qwer56</requestId>
tmp.txt 文件包含:
qwerty-qwer12-qwer56 : RequestId-1
这是完美的。问题是在处理许多字符串时,在 tmp.txt 文件中有比应有的更多的对。在下面的 tmp.txt 示例中,我应该看到“RequestId-x”的 4 倍,但有 6 个。此外,当同一行上有 2 个或更多“匹配”时,只有第一个被更新/替换。知道这些额外的行是从哪里来的吗?为什么脚本不会继续检查到同一行的末尾?
这是我的测试代码:
$log = "C:\log.txt"
$tmp = "C:\tmp.txt"
Clear-Content $log
Clear-Content $tmp
@'
<requestId>qwerty-qwer12-qwer56</requestId>qwertykeyId>Qwd84lPhjutf7Nmwr56hJndcsjy34imNQwd84lPhjutZ7Nmwr56hJndcsjy34imNPozDr5</ABC reportId>poGd56Hnm9q3Dfer6Jh</msg:reportId>
<requestId>zxcvbn-zxcv12-zxcv56</requestId>
<requestId>qwerty-qwer12-qwer56</requestId>abcde reportId>plmkjh8765FGH4rt6As</msg:reportId>
<requestId>1234qw-12qw12-12qw56</requestId>
keyId>Qwd84lPhjutf7Nmwr56hJndcsjy34imNQwd84lPhjutZ7Nmwr56hJndcsjy34imNPozDr5</
keyId>Qwd84lPhjutf7Nmwr56hJndcsjy34imNQwd84lPhjutZ7Nmwr56hJndcsjy34imNPozDr5</
keyId>Zdjgi76Gho3sQw0ib5Mjk3sDyoq9zmGdZdjgi76Gho3sQw0ib5Mjk3sDyoq9zmGdLkJpQw</
reportId>plmkjh8765FGH4rt6As</msg:reportId>
reportId>plmkjh8765FGH4rt6As</msg:reportId>
reportId>poGd56Hnm9q3Dfer6Jh</msg:reportId>
'@ | Set-Content $log -Encoding UTF8
$requestId = @{
Count = 1
Matches = @()
}
$keyId = @{
Count = 1
Matches = @()
}
$reportId = @{
Count = 1
Matches = @()
}
$output = switch -Regex -File $log {
'(\w{6}-\w{6}-\w{6})' {
if(!$requestId.matches.($matches.1))
{
$req = $requestId.matches += @{$matches.1 = "RequestId-$($requestId.count)"}
$requestId.count++
$req.keys | %{ Add-Content $tmp "$_ : $($req.$_)" }
}
$_ -replace $matches.1,$requestId.matches.($matches.1)
}
'keyId>(\w{70})</' {
if(!$keyId.matches.($matches.1))
{
$kid = $keyId.matches += @{$matches.1 = "keyId-$($keyId.count)"}
$keyId.count++
$kid.keys | %{ Add-Content $tmp "$_ : $($kid.$_)" }
}
$_ -replace $matches.1,$keyId.matches.($matches.1)
}
'reportId>(\w{19})</msg:reportId>' {
if(!$reportId.matches.($matches.1))
{
$repid = $reportId.matches += @{$matches.1 = "Report-$($reportId.count)"}
$reportId.count++
$repid.keys | %{ Add-Content $tmp "$_ : $($repid.$_)" }
}
$_ -replace $matches.1,$reportId.matches.($matches.1)
}
default {$_}
}
$output | Set-Content $log -Encoding UTF8
Get-Content $log
Get-Content $tmp
【问题讨论】:
-
存储用于 PoSh 的数据结构的常用方法是使用
Export/Import-CliXmlcmdlet。另一种是使用 JSON ......但 CliXml 的东西是为保存和恢复 PoSh 对象的完整结构而设计的。 -
您能告诉我们您用于
<keyId>标签的正则表达式模式吗?听起来你可能不小心截断了它 -
请在您的问题中添加minimal reproducible example。
-
问题已更新为相关代码。另一个问题是如果同一行上有 2 个匹配的字符串 - 仅更新第一个字符串,第二个保持不变,脚本继续到下一行。如何避免这种情况?
标签: powershell hashtable