使用PowerShell,我想用MyValue替换给定文件中所有精确出现的[MYID]。最简单的方法是什么?
当前回答
使用PowerShell中的当前工作目录,这对我来说很有效。您需要使用FullName属性,否则它将在PowerShell版本5中不起作用。我需要在所有CSPROJ文件中更改目标. net框架版本。
gci -Recurse -Filter *.csproj |
% { (get-content "$($_.FullName)")
.Replace('<TargetFramework>net47</TargetFramework>', '<TargetFramework>net462</TargetFramework>') |
Set-Content "$($_.FullName)"}
其他回答
用途(V3版本):
(Get-Content c:\temp\test.txt).replace('[MYID]', 'MyValue') | Set-Content c:\temp\test.txt
对于V2:
(Get-Content c:\temp\test.txt) -replace '\[MYID\]', 'MyValue' | Set-Content c:\temp\test.txt
示例替换文件夹内的所有字符串:
$path=$args[0]
$oldString=$args[1]
$newString=$args[2]
Get-ChildItem -Path $path -Recurse -File |
ForEach-Object {
(Get-Content $_.FullName).replace($oldString,$newString) | Set-Content $_.FullName
}
如果需要替换多个文件中的字符串:
值得注意的是,这里发布的不同方法在完成所需时间方面可能有很大不同。对我来说,我经常有大量的小文件。为了测试哪个性能最好,我在40,693个单独的文件中提取了5.52 GB(5,933,604,999字节)的XML,并运行了我在这里找到的三个答案:
## 5.52 GB (5,933,604,999 bytes) of XML files (40,693 files)
$xmls = (Get-ChildItem -Path "I:\TestseT\All_XML" -Recurse -Filter *.xml).FullName
#### Test 1 - Plain Replace
$start = Get-Date
foreach ($xml in $xmls) {
(Get-Content $xml).replace("'", " ") | Set-Content $xml
}
$end = Get-Date
New-TimeSpan –Start $Start –End $End
# TotalMinutes: 103.725113128333
#### Test 2 - Replace with -Raw
$start = Get-Date
foreach ($xml in $xmls) {
(Get-Content $xml -Raw).replace("'", " ") | Set-Content $xml
}
$end = Get-Date
New-TimeSpan –Start $Start –End $End
# TotalMinutes: 10.1600227983333
#### Test 3 - .NET, System.IO
$start = Get-Date
foreach ($xml in $xmls) {
$txt = [System.IO.File]::ReadAllText("$xml").Replace("'"," ")
[System.IO.File]::WriteAllText("$xml", $txt)
}
$end = Get-Date
New-TimeSpan –Start $Start –End $End
# TotalMinutes: 5.83619516833333
因为这个经常出现,我为它定义了一个函数。我默认使用区分大小写、基于正则表达式的匹配,但我添加了针对文字文本和忽略大小写的开关。
# Find and replace text in each pipeline string. Omit the -Replace parameter to delete
# text instead. Use the -SimpleMatch switch to work with literal text instead of regular
# expressions. Comparisons are case-sensitive unless the -IgnoreCase switch is used.
Filter Edit-String {
Param([string]$Find, [string]$Replace='', [switch]$SimpleMatch, [switch]$IgnoreCase)
if ($SimpleMatch) {
if ($IgnoreCase) {
return $_.Replace($Find, $Replace,
[System.StringComparison]::OrdinalIgnoreCase)
}
return $_.Replace($Find, $Replace)
}
if ($IgnoreCase) {
return $_ -replace $Find, $Replace
}
return $_ -creplace $Find, $Replace
}
Set-Alias replace Edit-String
Set-Alias sc Set-Content
使用
# 1 file
$f = a.txt; gc $f | replace '[MYID]' 'MyValue' -SimpleMatch | sc $f
# 0 to many files
gci *.txt | % { gc $_ | replace '\[MYID\]' 'MyValue' | sc $_ }
# Several replacements chained together
... | replace '[1-9]' T | replace a b -IgnoreCase | replace 'delete me' | ...
# Alias cheat sheet
# gci Get-ChildItem
# gc Get-Content
# sc Set-Conent
# % ForEach-Object
有点旧和不同,因为我需要在特定文件名的所有实例中更改某一行。
此外,Set-Content没有返回一致的结果,所以我不得不求助于Out-File。
下面的代码:
$FileName =''
$OldLine = ''
$NewLine = ''
$Drives = Get-PSDrive -PSProvider FileSystem
foreach ($Drive in $Drives) {
Push-Location $Drive.Root
Get-ChildItem -Filter "$FileName" -Recurse | ForEach {
(Get-Content $_.FullName).Replace($OldLine, $NewLine) | Out-File $_.FullName
}
Pop-Location
}
这是最适合我的PowerShell版本:
Major.Minor.Build.Revision 5.1.16299.98
推荐文章
- 如何运行一个PowerShell脚本而不显示窗口?
- PowerShell:仅为单个命令设置环境变量
- 是否有一种方法可以通过双击.ps1文件来使PowerShell脚本工作?
- PowerShell等价于grep -f
- “Write-Host”,“Write-Output”,或“[console]::WriteLine”之间的区别是什么?
- Powershell相当于bash的&号(&),用于分叉/运行后台进程
- PowerShell脚本在机器上返回。net框架的版本?
- 如何在PowerShell中获得MD5校验和
- 如何在PowerShell格式化日期时间
- PowerShell和-contains操作符
- 使用PowerShell删除超过15天的文件
- 数组添加 vs +=
- PowerShell中用户输入的提示符
- 如何从字符串执行任意本机命令?
- 如何使用。net 4运行时运行PowerShell ?