我正在尝试使用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
答案 0 :(得分:21)
尝试以下方法:
$file = 'D:\home\App_Config\Sitecore.config'
$regex = '(?<=<setting name="Media\.MediaLinkServerUrl" value=")[^"]*'
(Get-Content $file) -replace $regex, 'https://newurl.com' | Set-Content $file
*重新Set-Content
:它默认使用您系统的传统单字节字符编码,因此您可能希望使用-Encoding
来控制输出文件&#39;明确编码。
*另请注意(...)
调用所需的Get-Content
,以确保管道可以回写Get-Content
已读取的同一文件。
*如果有问题的开头标记(<setting ...>
)跨越多行,则使用
Get-Content -Raw $file
(PSv3 +)将整个文件内容读作单字符串(谢谢,deadlydog);
如果没有-Raw
,Get-Content
会返回字符串的数组,表示输入行。
由于使用正则表达式来匹配您现有的设置,因此当前value="..."
内的任何文本都匹配,因此即使重复运行,此命令也能正常工作
相比之下,您尝试的内容使用有效的文字(... value=" "
)来查找要替换的内容,并且在第一次成功运行之后,文字不再匹配,后续运行失败。
上述命令使用简化的替换方法:
(?<=<setting name="Media.MediaLinkServerUrl" value=")
是一个后视断言((?<=...)
)匹配,但没有捕获它匹配的内容:它找到包含开头{{ 1}}您尝试替换的价值,而不会将该前缀作为替换内容的一部分。
"
然后匹配整个值,但不包括结束[^"]*
。 ("
是一个字符集,匹配任何字符其他而不是[^"]
)和^
,"
找到任何(可能为空)序列这些人物。
因此,由于正则表达式仅捕获了值本身,因此您需要指定为替换字符串的是新值。
答案 1 :(得分:13)
使用这样的替换方法:
$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
答案 2 :(得分:0)
function Write-FileContent {
[cmdletBinding()]
param(
[parameter(Mandatory = $true)]
[string]$FileToReplacePath,
[parameter(Mandatory = $true)]
[string]$TextToReplaceWith,
[parameter(Mandatory = $true)]
[string]$LineNumber,
[parameter(Mandatory = $true)]
[string]$TextToBeingWith
)
$Read = Get-Content -Path $FileToReplacePath
$Read | ForEach-Object { if ($_.ReadCount -eq $LineNumber) { $_ -replace "'$TextToBeginWith'=.+'", "$TextToReplaceWith" } else { $_ } } | Set-Content $FileToReplacePath
}
$CsvFilePath="C:\msydatfgdfa.csv"
Write-FileContent -FileToReplacePath D:\test.txt -TextToReplaceWith "'$CsvFilePath'" -LineNumber 2 -TextToBeingWith "Infile"
答案 3 :(得分:0)
下面是保留PSPath属性的示例,因此您不必指定set-content的路径:
product_no part_no level last_part_no
0 1 1_1 1 nan
1 1 1_2 1 nan
2 1 1_3 2 1_2
3 1 1_4 1 nan
4 1 1_5 1 nan
5 1 1_6 2 1_5
6 1 1_7 2 1_5
7 1 1_8 3 1_7
8 1 1_9 3 1_7
9 1 1_10 2 1_5