好的,所以在看了一段时间之后,我决定必须有一种方法可以用一个衬里来做到这一点。这里是:
(gc "c:\myfile.txt") | % -Begin {$test = (gc "c:\myfile.txt" | select -first 1 -last 1)} -Process {if ( $_ -eq $test[0] -or $_ -eq $test[-1] ) { $_ -replace "-" } else { $_ }} | Set-Content "c:\myfile.txt"
以下是其作用的细分:
首先,现在熟悉的别名。我只是把它们放进去,因为命令足够长,所以这有助于保持事情的可管理性:
-
gc 表示 Get-Content
-
% 表示 Foreach
-
$_ 用于当前管道值(这不是别名,但我想我会定义它,因为你说你是新人)
好的,现在是这里发生的事情:
-
(gc "c:\myfile.txt") | --> 获取c:\myfile.txt 的内容并发送给下一行
-
% --> 执行 foreach 循环(分别遍历管道中的每个项目)
-
-Begin {$test = (gc "c:\myfile.txt" | select -first 1 -last 1)} --> 这是一个开始块,它在进入管道之前运行这里的所有内容。它将c:\myfile.txt 的第一行和最后一行加载到一个数组中,以便我们检查第一个和最后一个项目
-
-Process {if ( $_ -eq $test[0] -or $_ -eq $test[-1] ) --> 这将对管道中的每个项目进行检查,检查它是文件中的第一项还是最后一项
-
{ $_ -replace "-" } else { $_ } --> 如果是第一个或最后一个,它会替换,如果不是,它就不管它
-
| Set-Content "c:\myfile.txt" --> 这会将新值放回文件中。
有关这些项目的更多信息,请访问以下网站:
Get-Content uses
Get-Content definition
Foreach
The Pipeline
Begin and Process Foreach 的一部分(这通常用于自定义函数,但它们在 foreach 循环中作为好吧)
If ... else声明
Set-Content
所以我在想,如果您想对许多文件执行此操作,或者想要经常执行此操作,该怎么办。我决定制作一个功能来满足您的要求。这是函数:
function Replace-FirstLast {
[CmdletBinding()]
param(
[Parameter( `
Position=0, `
Mandatory=$true)]
[String]$File,
[Parameter( `
Position=1, `
Mandatory=$true)]
[ValidateNotNull()]
[regex]$Regex,
[Parameter( `
position=2, `
Mandatory=$false)]
[string]$ReplaceWith=""
)
Begin {
$lines = Get-Content $File
} #end begin
Process {
foreach ($line in $lines) {
if ( $line -eq $lines[0] ) {
$lines[0] = $line -replace $Regex,$ReplaceWith
} #end if
if ( $line -eq $lines[-1] ) {
$lines[-1] = $line -replace $Regex,$ReplaceWith
}
} #end foreach
}#End process
end {
$lines | Set-Content $File
}#end end
} #end function
这将创建一个名为Replace-FirstLast 的命令。它会被这样调用:
Replace-FirstLast -File "C:\myfiles.txt" -Regex "-" -ReplaceWith "NewText"
-Replacewith 是可选的,如果它为空,它将被删除(默认值为"")。 -Regex 正在寻找一个正则表达式来匹配您的命令。有关将其放入您的个人资料的信息,请查看this article
请注意:如果您的文件非常大(几 GB),这不是最佳解决方案。这会导致整个文件驻留在内存中,这可能会导致其他问题。