假设我有一个名为testfile.txt的测试文件,它包含以下行:
one (two) "three"我想使用PowerShell来表示,如果整个字符串存在,那么将一行直接放在它下面,其值如下:
four (five) "six" (请注意,它包括空格、括号和双引号。这是很重要的,因为我遇到的问题是我认为摆脱括号和双引号)。
因此,结果将是:
one (two) "three"
four (five) "six" 我认为最简单的方法是,如果找到了第一个字符串,将其替换为第一个字符串本身,新字符串将形成一个包含在同一命令中的新行。我在排列字符串时遇到了困难,所以我尝试使用一个具有格式的完整文本块来读取该字符串变量。它仍然不解析带引号的完整字符串到管道中。我刚接触过powershell,所以如果你看到一些愚蠢的东西,不要退缩。
$herestring1 = @"
one (two) "three"
"@
$herestring2 = @"
one (two) "three"
four (five) "six"
"@
if((Get-Content testfile.txt) | select-string $herestring1) {
"Match found - replacing string"
(Get-Content testfile.txt) | ForEach-Object { $_ -replace $herestring1,$herestring2 } | Set-Content ./testfile.txt
"Replaced string successfully"
}
else {
"No match found"}上面只给出了“没有找到匹配”的每次。这是因为它找不到文件中的第一个字符串。我尝试过使用回勾和加倍引号来尝试转义,但我认为这里字符串的要点是它应该解析文本块,包括所有格式,这样我就不必这样做了。
如果我将文件更改为仅包含:
one two three然后相应地将下面的字符串更改为:
$herestring1 = @"
one two three
"@
$herestring2 = @"
one two three
four five six
"@然后它工作正常,我得到了我想要更换的字符串。
发布于 2016-10-17 14:46:38
正如Martin所指出的,您可以将-SimpleMatch与Select-String一起使用,以避免将其解析为正则表达式。
但-replace仍将使用正则表达式。
您可以使用RegEx使用[RegEx]::Escape()转义模式。
$herestring1 = @"
one (two) "three"
"@
$herestring2 = @"
one (two) "three"
four (five) "six"
"@
$pattern1 = [RegEx]::Escape($herestring1)
if((Get-Content testfile.txt) | select-string $pattern1) {
"Match found - replacing string"
(Get-Content testfile.txt) | ForEach-Object { $_ -replace $pattern1,$herestring2 } | Set-Content ./testfile.txt
"Replaced string successfully"
}
else {
"No match found"}正则表达式将括号() (您所称的括号)解释为特殊。默认情况下,空格不是特殊的,但它们可以具有某些正则表达式选项。双引号没问题。
在regex中,转义字符是反斜杠\,这与使用回勾`为PowerShell解析器所做的任何转义无关。
[RegEx]::Escape()将确保对regex具有特殊意义的内容转义,以便regex模式将其解释为文字,因此您的模式最终将如下所示:one\ \(two\)\ "three"
发布于 2016-10-17 14:42:20
只需在Select-String开关中使用-SimpleMatch cmdlet:
# ....
if((Get-Content testfile.txt) | select-string -SimpleMatch $herestring1) {
# ....-SimpleMatch
指示cmdlet使用简单匹配而不是正则表达式匹配。在简单匹配中,Select搜索模式参数中的文本输入。它不将模式参数的值解释为正则表达式语句。
https://stackoverflow.com/questions/40089257
复制相似问题