PowerShell的:使用哈希表

问题描述:

好了替换字符串,所以我给自己定了一个哈希表的名字是什么,以取代和钥匙是做什么用代替,就像这样:PowerShell的:使用哈希表

$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

什么是C的含量:\脚本\ test.txt的? –

下面是做这件事:

$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循环;替换可以针对每个哈希表项一次传递全文。

+0

的foreach($在R $ E)工程,以及$ r.GetEnumerator()。 –

+0

谢谢!像魅力一样工作。 – khvn

+0

好点@Christian,GetEnumerator()调用并没有真正完成任何事情。删除。 – ajk

我得到了它以这种方式工作

foreach ($i in $HashTable.Keys) { 
    $myString = $myString -replace $i, $HashTable[$i] 
} 

根据您的文件和哈希表,有各种优化,你可以考虑:

  1. 您可以从哈希表中建立一个正则表达式这样的密钥集合:

    $regexes = $r.keys | foreach {[System.Text.RegularExpressions.Regex]::Escape($_)} 
    $regex = [regex]($r.Keys -join '|')  
    

    在这样做,你不会迭代每个键,但n你需要知道你匹配哪个键才能获得替换。另一方面,执行字符串替换可能会更快,而不是正则表达式替换(或者像字符串拆分和联接过程那样更复杂)。

  2. 在PowerShell中,你可以调用.NET Regex::Replace功能:

    字符串替换(字符串输入,System.Text.RegularExpressions.MatchEvaluator评估)

    调用此方法可以定义一个MatchEvaluator,象这样一个脚本块:

    $callback = { $r[$args[0].Value] } 
    

    在脚本块,$args[0]System.Text.RegularExpressions.Match,因此您可以使用其Value属性来索引$r散列表。

  3. Get-Content返回一个字符串数组,这对-replace运算符来说很好,但也意味着一个额外的循环运行。 [System.IO.File]::ReadAllText将返回一个单一的字符串,所以正则表达式只需要解析一次。

    $file = [System.IO.File]::ReadAllText("C:\scripts\test.txt") 
    
  4. 如果使用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 
+1

为了使它不区分大小写,使用'$正则表达式= [正则表达式( “(我)?” +($正则表达式-join '|'))' – sparebytes