PowerShell - 查找并替换多个模式以匿名化文件

PowerShell - Find and replace multiple patterns to anonymize file

我需要你的帮助。我有一个 log.txt 文件,其中包含我必须匿名的各种数据。 我想检索所有这些匹配预定义模式的“字符串”,并将它们替换为每个字符串的另一个值。重要的是来自相同模式的每个新字符串(并且与之前的值不同)应该被增加+1的预定义值替换(例如“orderID = 123ABC”变成“orderID = order1”和“orderID = 456ABC " 变成 "orderID=order2").
要搜索的模式超过 20 个,因此不可能将它们全部放在一行中。 我的想法是:

  1. 定义“patterns.txt”文件
  2. 定义“replace.txt”文件(“模式”值和替换值)
  3. 在日志文件中搜索所有“模式”,结果将为 ARRAY
  4. 找到该 ARRAY 中的唯一条目
  5. 获取 ARRAY 中每个唯一条目的“替换”值
  6. 替换 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>