如何使用PowerShell替换文件中的行?

neh*_*eha 17 powershell

我试图阅读使用PowerShell替换配置文件中的一行.有时这个脚本有效,但大多数情况下它不会替换该行.

(Get-Content D:\home\App_Config\Sitecore.config) `
    | %{ $_ -replace '  <setting name="Media.MediaLinkServerUrl" value=" "/>',' <setting name="Media.MediaLinkServerUrl" value="https://newurl.com"/>'} `
    | Set-Content D:\home\App_Config\Sitecore.config
Run Code Online (Sandbox Code Playgroud)

mkl*_*nt0 24

请尝试以下方法:

$file = 'D:\home\App_Config\Sitecore.config'
$regex = '(?<=<setting name="Media\.MediaLinkServerUrl" value=")[^"]*'
(Get-Content $file) -replace $regex, 'https://newurl.com' | Set-Content $file
Run Code Online (Sandbox Code Playgroud)

*Re Set-Content:它默认使用系统的传统单字节字符编码,因此您可能希望使用-Encoding显式控制输出文件的编码.
*还要注意调用(...)周围所需的内容,Get-Content以确保管道可以回写到Get-Content已读取的同一文件.
*如果有问题(<setting ...>)的开头标签有可能跨越多行,请使用
Get-Content -Raw $file(PSv3 +)将整个文件内容作为单个字符串读取(谢谢,致命狗狗);
without -Raw,Get-Content返回一个字符串数组,表示输入.

由于使用正则表达式来匹配现有设置,因此当前内部的任何文本value="..."都匹配,因此即使重复运行此命令也会起作用.

相比之下,您尝试使用有效的literal(... value=" ")来查找要替换的内容,并且在第1次成功运行之后,该文字不再匹配,并且后续运行失败.

上面的命令使用简化的替换方法:

  • (?<=<setting name="Media.MediaLinkServerUrl" value=")是一个后视断言((?<=...))匹配,但不捕获它匹配的内容:它找到了部分,包括"你试图替换的值的开头,而没有使该前缀成为将要获得的内容的一部分更换.

  • [^"]*然后匹配整个值,最多但不包括结束".([^"]是匹配任何字符的字符集的其它比(^)一个",并*发现这样的字符的任何(可能是空的)序列.

  • 因此,因为正则表达式仅捕获值本身,所以您需要指定为替换字符串的是新值.


Jam*_* C. 14

像这样使用Replace方法:

$file = 'D:\home\App_Config\Sitecore.config'
$find = '  <setting name="Media.MediaLinkServerUrl" value=" "/>'
$replace = ' <setting name="Media.MediaLinkServerUrl" value="https://newurl.com"/>'

(Get-Content $file).replace($find, $replace) | Set-Content $file
Run Code Online (Sandbox Code Playgroud)

  • @mklement0的回答比我好,他知道正则表达的黑暗艺术.我在巫师学校错过了那堂课;) (3认同)
  • `.Replace()` 是 .NET 类型 `[string]` 的 _method_,而不是 _operator_。与使用正则表达式的 PowerShell 的 `-replace` 运算符不同,`.Replace()` 执行 _literal_ 子字符串替换,我怀疑这可能是 neha 的问题:在脚本的初始(成功)运行后,文字不再匹配. (2认同)