PowerShell - 查找并替换多个模式以匿名化文件
PowerShell - Find and replace multiple patterns to anonymize file
我需要你的帮助。我有一个 log.txt 文件,其中包含我必须匿名的各种数据。
我想检索所有这些匹配预定义模式的“字符串”,并将它们替换为每个字符串的另一个值。重要的是来自相同模式的每个新字符串(并且与之前的值不同)应该被增加+1的预定义值替换(例如“orderID = 123ABC”变成“orderID = order1”和“orderID = 456ABC " 变成 "orderID=order2").
要搜索的模式超过 20 个,因此不可能将它们全部放在一行中。
我的想法是:
- 定义“patterns.txt”文件
- 定义“replace.txt”文件(“模式”值和替换值)
- 在日志文件中搜索所有“模式”,结果将为 ARRAY
- 找到该 ARRAY 中的唯一条目
- 获取 ARRAY 中每个唯一条目的“替换”值
- 替换 log.txt 中的所有匹配项。这里棘手的部分是任何相同类型的出现(但与前一个不同的值)需要增加(+1)才能与之前的不同。
我的示例:
requestID>qwerty1-qwerty2-qwerty3</requestID
requestID>12345a-12345b-12345c</requestID
requestID>qwerty1-qwerty2-qwerty3</requestID
requestID>qwerty1-qwerty2-qwerty3</requestID
orderID>012345ABCDE</orderID
orderID>012345ABCDE</orderID
orderID>ABCDE012345</orderID
orderID>ABCDE012345</orderID
keyId>XYZ123</keyId
keyId>ABC987</keyId
keyId>XYZ123</keyId
想要的结果:
requestID>Request-1</requestID
requestID>Request-2</requestID
requestID>Request-1</requestID
requestID>Request-1</requestID
orderID>Order-1</orderID
orderID>Order-1</orderID
orderID>Order-2</orderID
orderID>Order-2</orderID
keyId>Key-1</keyId
keyId>Key-2</keyId
keyId>Key-1</keyId
目前我只找到了每种类型的唯一值:
$N = "C:\FindAndReplace\input.txt"
$Patterns = "C:\FindAndReplace\pattern.txt"
(Select-String $N -Pattern 'requestID>\w{6}-\w{6}-\w{6}</requestID>').Matches.Value | Sort-Object -Descending -Unique
(Select-String $N -Pattern '<orderID>\w{20}</orderID>').Matches.Value | Sort-Object -Descending -Unique
(Select-String $N -Pattern '<keyId>\w{8}</keyId>').Matches.Value | Sort-Object -Descending -Unique
在此先感谢您就如何推进提出任何建议。
您的模式与示例数据不匹配。我已更正模式以适应实际示例数据。
似乎每种类型的简单散列 table 都可以满足跟踪匹配和计数的需要。如果我们使用 -Regex
和 -File
参数使用 switch
语句处理日志文件,我们可以一次处理每一行。每个的逻辑是
- 检查当前匹配项是否存在于特定类型的匹配项数组中。
- 如果不是,请添加它的替换值 (type-count) 和增量计数。
- 如果存在,使用已经定义的替换值。
- 捕获变量中的所有输出,然后在完成后将其写入文件。
创建示例日志文件
$log = New-TemporaryFile
@'
<requestID>qwerty1-qwerty2-qwerty3</requestID> -match
<requestID>12345a-12345b-12345c</requestID>
<requestID>qwerty1-qwerty2-qwerty3</requestID>
<requestID>qwerty1-qwerty2-qwerty3</requestID>
<orderID>012345ABCDE</orderID>
<orderID>012345ABCDE</orderID>
<orderID>ABCDE012345</orderID>
<orderID>ABCDE012345</orderID>
<keyId>XYZ123</keyId>
<keyId>ABC987</keyId>
<keyId>XYZ123</keyId>
'@ | Set-Content $log -Encoding UTF8
为包含计数和匹配数组的每种类型定义“跟踪器”变量
$Request = @{
Count = 1
Matches = @()
}
$Order = @{
Count = 1
Matches = @()
}
$Key = @{
Count = 1
Matches = @()
}
逐行读取并处理日志文件
$output = switch -Regex -File $log {
'<requestID>(\w{6,7}-\w{6,7}-\w{6,7})</requestID>' {
if(!$Request.matches.($matches.1))
{
$Request.matches += @{$matches.1 = "Request-$($Request.count)"}
$Request.count++
}
$_ -replace $matches.1,$Request.matches.($matches.1)
}
'<orderID>(\w{11})</orderID>' {
if(!$Order.matches.($matches.1))
{
$Order.matches += @{$matches.1 = "Order-$($Order.count)"}
$Order.count++
}
$_ -replace $matches.1,$Order.matches.($matches.1)
}
'<keyId>(\w{6})</keyId>' {
if(!$Key.matches.($matches.1))
{
$Key.matches += @{$matches.1 = "Key-$($Key.count)"}
$Key.count++
}
$_ -replace $matches.1,$Key.matches.($matches.1)
}
default {$_}
}
$output | Set-Content $log -Encoding UTF8
$log 文件现在包含
<requestID>Request-1</requestID>
<requestID>Request-2</requestID>
<requestID>Request-1</requestID>
<requestID>Request-1</requestID>
<orderID>Order-1</orderID>
<orderID>Order-1</orderID>
<orderID>Order-2</orderID>
<orderID>Order-2</orderID>
<keyId>Key-1</keyId>
<keyId>Key-2</keyId>
<keyId>Key-1</keyId>
我需要你的帮助。我有一个 log.txt 文件,其中包含我必须匿名的各种数据。
我想检索所有这些匹配预定义模式的“字符串”,并将它们替换为每个字符串的另一个值。重要的是来自相同模式的每个新字符串(并且与之前的值不同)应该被增加+1的预定义值替换(例如“orderID = 123ABC”变成“orderID = order1”和“orderID = 456ABC " 变成 "orderID=order2").
要搜索的模式超过 20 个,因此不可能将它们全部放在一行中。
我的想法是:
- 定义“patterns.txt”文件
- 定义“replace.txt”文件(“模式”值和替换值)
- 在日志文件中搜索所有“模式”,结果将为 ARRAY
- 找到该 ARRAY 中的唯一条目
- 获取 ARRAY 中每个唯一条目的“替换”值
- 替换 log.txt 中的所有匹配项。这里棘手的部分是任何相同类型的出现(但与前一个不同的值)需要增加(+1)才能与之前的不同。
我的示例:
requestID>qwerty1-qwerty2-qwerty3</requestID
requestID>12345a-12345b-12345c</requestID
requestID>qwerty1-qwerty2-qwerty3</requestID
requestID>qwerty1-qwerty2-qwerty3</requestID
orderID>012345ABCDE</orderID
orderID>012345ABCDE</orderID
orderID>ABCDE012345</orderID
orderID>ABCDE012345</orderID
keyId>XYZ123</keyId
keyId>ABC987</keyId
keyId>XYZ123</keyId
想要的结果:
requestID>Request-1</requestID
requestID>Request-2</requestID
requestID>Request-1</requestID
requestID>Request-1</requestID
orderID>Order-1</orderID
orderID>Order-1</orderID
orderID>Order-2</orderID
orderID>Order-2</orderID
keyId>Key-1</keyId
keyId>Key-2</keyId
keyId>Key-1</keyId
目前我只找到了每种类型的唯一值:
$N = "C:\FindAndReplace\input.txt"
$Patterns = "C:\FindAndReplace\pattern.txt"
(Select-String $N -Pattern 'requestID>\w{6}-\w{6}-\w{6}</requestID>').Matches.Value | Sort-Object -Descending -Unique
(Select-String $N -Pattern '<orderID>\w{20}</orderID>').Matches.Value | Sort-Object -Descending -Unique
(Select-String $N -Pattern '<keyId>\w{8}</keyId>').Matches.Value | Sort-Object -Descending -Unique
在此先感谢您就如何推进提出任何建议。
您的模式与示例数据不匹配。我已更正模式以适应实际示例数据。
似乎每种类型的简单散列 table 都可以满足跟踪匹配和计数的需要。如果我们使用 -Regex
和 -File
参数使用 switch
语句处理日志文件,我们可以一次处理每一行。每个的逻辑是
- 检查当前匹配项是否存在于特定类型的匹配项数组中。
- 如果不是,请添加它的替换值 (type-count) 和增量计数。
- 如果存在,使用已经定义的替换值。
- 捕获变量中的所有输出,然后在完成后将其写入文件。
创建示例日志文件
$log = New-TemporaryFile
@'
<requestID>qwerty1-qwerty2-qwerty3</requestID> -match
<requestID>12345a-12345b-12345c</requestID>
<requestID>qwerty1-qwerty2-qwerty3</requestID>
<requestID>qwerty1-qwerty2-qwerty3</requestID>
<orderID>012345ABCDE</orderID>
<orderID>012345ABCDE</orderID>
<orderID>ABCDE012345</orderID>
<orderID>ABCDE012345</orderID>
<keyId>XYZ123</keyId>
<keyId>ABC987</keyId>
<keyId>XYZ123</keyId>
'@ | Set-Content $log -Encoding UTF8
为包含计数和匹配数组的每种类型定义“跟踪器”变量
$Request = @{
Count = 1
Matches = @()
}
$Order = @{
Count = 1
Matches = @()
}
$Key = @{
Count = 1
Matches = @()
}
逐行读取并处理日志文件
$output = switch -Regex -File $log {
'<requestID>(\w{6,7}-\w{6,7}-\w{6,7})</requestID>' {
if(!$Request.matches.($matches.1))
{
$Request.matches += @{$matches.1 = "Request-$($Request.count)"}
$Request.count++
}
$_ -replace $matches.1,$Request.matches.($matches.1)
}
'<orderID>(\w{11})</orderID>' {
if(!$Order.matches.($matches.1))
{
$Order.matches += @{$matches.1 = "Order-$($Order.count)"}
$Order.count++
}
$_ -replace $matches.1,$Order.matches.($matches.1)
}
'<keyId>(\w{6})</keyId>' {
if(!$Key.matches.($matches.1))
{
$Key.matches += @{$matches.1 = "Key-$($Key.count)"}
$Key.count++
}
$_ -replace $matches.1,$Key.matches.($matches.1)
}
default {$_}
}
$output | Set-Content $log -Encoding UTF8
$log 文件现在包含
<requestID>Request-1</requestID>
<requestID>Request-2</requestID>
<requestID>Request-1</requestID>
<requestID>Request-1</requestID>
<orderID>Order-1</orderID>
<orderID>Order-1</orderID>
<orderID>Order-2</orderID>
<orderID>Order-2</orderID>
<keyId>Key-1</keyId>
<keyId>Key-2</keyId>
<keyId>Key-1</keyId>