[英]How do I replace a line in a file using PowerShell?
I am trying to read replace a line in a configuration file using PowerShell.我正在尝试使用 PowerShell 读取替换配置文件中的一行。 Sometimes this script works, but most of the time it does not replace the line.
有时此脚本有效,但大多数情况下它不会替换该行。
(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
Try the following:请尝试以下操作:
$file = 'D:\home\App_Config\Sitecore.config'
$regex = '(?<=<setting name="Media\.MediaLinkServerUrl" value=")[^"]*'
(Get-Content $file) -replace $regex, 'https://newurl.com' | Set-Content $file
* Re Set-Content
: In Windows PowerShell it uses your system's legacy single-byte character encoding by default (based on the active ANSI code page), so you may want to use -Encoding
to control the output file's encoding explicitly; * 重新
Set-Content
:在Windows PowerShell 中,它默认使用您系统的旧单字节字符编码(基于活动的 ANSI 代码页),因此您可能希望使用-Encoding
显式控制输出文件的编码; PowerShell [Core] 6+ defaults to BOM-less UTF-8. PowerShell [Core] 6+默认为无 BOM 的 UTF-8。
(...)
around the Get-Content
call to ensure that the pipeline can write back to the same file that Get-Content
has read from.Get-Content
调用周围的必需(...)
,以确保管道可以写回Get-Content
已从中读取的同一文件。<setting ...>
) spans multiple lines , use<setting ...>
)有可能跨越多行,请使用Get-Content -Raw $file
(PSv3+) to read the entire file content as a single string (thanks, deadlydog ); Get-Content -Raw $file
(PSv3+) 将整个文件内容作为单个字符串读取(谢谢, deadlydog );-Raw
, Get-Content
returns an array of strings, representing the input lines .-Raw
, Get-Content
返回一个字符串数组,表示输入行。 Due to using a regular expression to match your existing setting, any text currently inside value="..."
is matched, so this command will work even when run repeatedly .由于使用正则表达式来匹配您现有的设置,当前在
value="..."
任何文本都会匹配,因此即使重复运行此命令也能正常工作。
By contrast, what you tried uses an effective literal ( ... value=" "
) to find what to replace, and after the 1st - successful - run, that literal no longer matches, and subsequent runs have no effect.相比之下,您尝试使用有效文字(
... value=" "
) 来查找要替换的内容,并且在第一次成功运行后,该文字不再匹配,后续运行无效。
The command above uses a streamlined approach to replacement:上面的命令使用了一种简化的替换方法:
(?<=<setting name="Media.MediaLinkServerUrl" value=")
is a look-behind assertion ( (?<=...)
) that matches, but doesn't capture what it matches: it finds the part up to and including the opening "
of the value you're trying to replaces, without making that prefix a part of what will get replaced. (?<=<setting name="Media.MediaLinkServerUrl" value=")
是匹配的后视断言( (?<=...)
),但不捕获它匹配的内容:它找到了部分到并包括您要替换的值的开头"
,而不将该前缀作为将被替换的内容的一部分。
[^"]*
then matches the entire value, up to, but not including the closing "
. [^"]*
然后匹配整个值,直到但不包括结束的"
。 ( [^"]
is a character set that matches any character other than ( ^
) a "
, and *
finds any (possibly empty) sequence of such characters. (
[^"]
是比其他任何字符相匹配的字符集( ^
)一个"
,和*
找到这样任何字符(可能是空的)序列。
Therefore, because the regex captured only the value itself, all you need to specify as the replacement string is the new value.因此,由于正则表达式仅捕获值本身,因此您需要指定的替换字符串就是新值。
Use the Replace method like this:像这样使用 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
I am trying to replace anything come after Infile我正在尝试替换 Infile 之后的任何内容
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"
Here's an example that preserves the PSPath property, so you don't have to specify the path to set-content:这是一个保留 PSPath 属性的示例,因此您不必指定 set-content 的路径:
(Get-Content -raw input) | ForEach-Object {
$_ -replace 111,222 |
Add-Member NoteProperty PSPath $_.PSPath -PassThru
} | Set-Content -nonewline
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.