好的,所以我设置了一个哈希表,其中的名称是要替换的名称,键是要替换的内容,如下所示:
$r = @{
"dog" = "canine";
"cat" = "feline";
"eric" = "eric cartman"
}
接下来我该怎么办?我试过这个:
(Get-Content C:\scripts\test.txt) | Foreach-Object {
foreach ( $e in $r.GetEnumerator() ) {
$_ -replace $e.Name, $e.Value
}
} | Set-Content C:\scripts\test.txt.out
但它根本不起作用,它只是将每一行写入三次,而不更换任何东西。
编辑:包含test.txt:
dog
cat
eric
test.txt.out:
dog
dog
dog
cat
cat
cat
eric
eric
eric
答案 0 :(得分:7)
这是一种方法:
$file = Get-Content C:\scripts\test.txt
foreach ($e in $r) {
$file = $file -replace $e.Name, $e.Value
}
Set-Content -Path C:\scripts\test.txt.out -Value $file
你看到每一行三次的原因是由于嵌套的foreach循环。对于文件中的每一行,每个哈希表条目运行一次替换操作。这不会更改源文件,但默认情况下它会输出替换的结果(即使没有更改)。
您可以先将文件读入变量,然后使用循环替换来更新该变量,从而获得所需的功能。您也不需要为文件内容单独的foreach循环;每个哈希表条目一次传递时,替换可以针对全文运行。
答案 1 :(得分:4)
根据您的文件和哈希表,您可以考虑各种优化:
您可以从哈希表键集合中构建正则表达式,如下所示:
$regexes = $r.keys | foreach {[System.Text.RegularExpressions.Regex]::Escape($_)}
$regex = [regex]($r.Keys -join '|')
在执行此操作时,您不会迭代每个键,但现在您需要知道您匹配的键才能获得替换。另一方面,执行字符串替换而不是正则表达式替换(或更复杂的字符串拆分和连接过程)可能更快。
在Powershell中,您可以调用.NET Regex::Replace
函数:
string Replace(string input,System.Text.RegularExpressions.MatchEvaluator evaluationator)
调用此方法,您可以使用如下的脚本块定义MatchEvaluator
:
$callback = { $r[$args[0].Value] }
在scriptblock中,$args[0]
是System.Text.RegularExpressions.Match
,因此您可以使用其Value
属性来索引$r
哈希表。
Get-Content
返回一个字符串数组,对-replace
运算符很好,但也意味着运行了一个额外的循环。 [System.IO.File]::ReadAllText
将返回一个字符串,因此只需要解析一次正则表达式。
$file = [System.IO.File]::ReadAllText("C:\scripts\test.txt")
如果您使用Get-Content
,要使用$regex.Replace
(而不是-replace
),则需要循环:
$file = $file | % { $regex.Replace($_, $callback) }
由于我不是,我可以使用一个替换呼叫:
$file = $regex.Replace($file, $callback)
因此完整的脚本:
$r = @{
"dog" = "canine";
"cat" = "feline";
"eric" = "eric cartman"
}
$regexes = $r.keys | foreach {[System.Text.RegularExpressions.Regex]::Escape($_)}
$regex = [regex]($regexes -join '|')
$callback = { $r[$args[0].Value] }
$file = [System.IO.File]::ReadAllText("C:\scripts\test.txt")
$file = $regex.Replace($file, $callback)
Set-Content -Path C:\scripts\test.txt.out -Value $file
答案 2 :(得分:3)
我用这种方式工作
foreach ($i in $HashTable.Keys) {
$myString = $myString -replace $i, $HashTable[$i]
}