简体   繁体   English

PowerShell 使用字符串数组查找和替换

[英]PowerShell find and replace using an array of strings

I'm wanting to comb through an LDIF file for 28 strings to replace.我想梳理一个 LDIF 文件以替换 28 个字符串。 I have two arrays, one for the find, and another for the replace items.我有两个数组,一个用于查找,另一个用于替换项。

The replace is working, but is then overwritten on the next iteration.替换正在工作,但在下一次迭代时被覆盖。 I don't know how to keep the existing file intact and only change the row with the string needing replaced.我不知道如何保持现有文件完好无损,只更改需要替换字符串的行。


$find = @(  "Code=2092",
            "Code=3257",
            "Code=3044",
            "Code=3001"
)

$replace = @(
                "|(Code=2092)(Code=9191)(Code=9192)(Code=9193)(Code=9194)",
                "|(Code=3257)(Code=5581)(Code=5582)(Code=5583)(Code=5584)",
                "|(Code=3044)(Code=5591)(Code=5592)(Code=5593)(Code=5594)",
                "|(Code=3001)(Code=5601)(Code=5602)(Code=5603)(Code=5604)"
)

$filePath = 'C:\Users\tim\Codes\export.ldf'
$tempFilePath = 'C:\Users\tim\Codes\temp.ldf'

$i = $find.Length
Write-Output $i

for ($n = 0; $n -lt $i + 1; $n++)
{ 
    (Get-Content -Path $filePath) | ForEach-Object {$_ -replace $find[$n], $replace[$n]} | Add-Content -Path $tempFilePath
    Write-Output $n
    Write-Output $i
}
Remove-Item -Path $filePath
Write-Output "Finished with Array"
Move-Item -Path $tempFilePath -Destination $filePath

A Sample input is:样本输入是:

#This LDIF file
version: 1


dn:cn=DG-C-10292-718200,OU=R,DC=ORG
changetype:add
QueryURL:ldap:///OU=Codes,DC=Org??one?(&(Reference=718200)(Code=10292)(!(State=Stale)))

dn:cn=DG-C-10325-764792,OU=R,DC=ORG
changetype:add
QueryURL:ldap:///OU=Codes,DC=Org??one?(&(Code=10325)(Reference=764792)(!(State=Stale)))

dn:cn=DG-C-10400-519400,OU=R,DC=ORG
changetype:add
QueryURL:ldap:///OU=Codes,DC=Org??one?(&(Reference=519400)(Code=10400)(!(State=Stale)))

dn:cn=DG-C-10454-745581,OU=R,DC=ORG
changetype:add
QueryURL:ldap:///OU=Codes,DC=Org??one?(&(Reference=745581)(Code=10454)(!(State=Stale)))

dn:cn=DG-C-10547-115900,OU=R,DC=ORG
changetype:add
QueryURL:ldap:///OU=Codes,DC=Org??one?(&(Reference=115900)(Code=10547)(!(State=Stale)))

dn:cn=DG-C-10548-719708,OU=R,DC=ORG
changetype:add
QueryURL:ldap:///OU=Codes,DC=Org??one?(&(Reference=719708)(Code=10548)(!(State=Stale)))

dn:cn=DG-C-10548-719715,OU=R,DC=ORG
changetype:add
QueryURL:ldap:///OU=Codes,DC=Org??one?(&(Reference=719715)(Code=10548)(!(State=Stale)))

dn:cn=DG-C-10550-719700,OU=R,DC=ORG
changetype:add
QueryURL:ldap:///OU=Codes,DC=Org??one?(&(Reference=719700)(Code=10550)(!(State=Stale)))

dn:cn=DG-C-10572-719714,OU=R,DC=ORG
changetype:add
QueryURL:ldap:///OU=Codes,DC=Org??one?(&(Reference=719714)(Code=10572)(!(State=Stale)))

dn:cn=DG-C-10578-719700,OU=R,DC=ORG
changetype:add
QueryURL:ldap:///OU=Codes,DC=Org??one?(&(Reference=719700)(Code=10578)(!(State=Stale)))

dn:cn=DG-C-10580-718600,OU=R,DC=ORG
changetype:add
QueryURL:ldap:///OU=Codes,DC=Org??one?(&(Reference=718600)(Code=10580)(!(State=Stale)))

I was thinking of something like this, but not 100% sure if that's what you want我在想这样的事情,但不能 100% 确定这是否是你想要的

Get-Content $filePath  | foreach {
    for ($i = 0; $i -lt $find.Count; $i++) {
        if ($_.Contains($find[$i])) {
            return $_.Replace($find[$i], $replace[$i])
        }
    }
    $_
} | Set-Content $tempFilePath
# Construct a hashtable that maps the search terms
# to their replacements.
$replacementMap = @{
  'Code=2092' = '|(Code=2092)(Code=9191)(Code=9192)(Code=9193)(Code=9194)'
  'Code=3257' = '|(Code=3257)(Code=5581)(Code=5582)(Code=5583)(Code=5584)'
  'Code=3044' = '|(Code=3044)(Code=5591)(Code=5592)(Code=5593)(Code=5594)'
  'Code=3001' = '|(Code=3001)(Code=5601)(Code=5602)(Code=5603)(Code=5604)'
}

# Read the input file as a single string (thanks to -Raw),
# construct a regex that matches any of the keys (search terms),
# and use a script block to replace each match with the corresponding
# replacement string.
[regex]::Replace(
  (Get-Content -Raw $filePath),
  ($replacementMap.Keys -join '|'),
  { param($match) $replacementMap[$match.Value] }
)

The above makes use of the [regex]::Replace() method, which is required to make the solution work in Windows PowerShell .以上使用了[regex]::Replace()方法,这是使解决方案在Windows PowerShell 中工作所必需的。

Note that PowerShell (Core) 7+ now offers using script blocks as the substitution operand directly with the -replace operator , which allows simplifying the solution to (the match at hand is implicitly available via the automatic $_ variable ):请注意, PowerShell (Core) 7+现在提供使用脚本块作为直接与-replace运算符的替换操作数,这允许简化解决方案(手头的匹配通过自动$_变量隐式可用):

(Get-Content -Raw $filePath) -replace ($replacementMap.Keys -join '|'),
                                      { $replacementMap[$_.Value] }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM