请解释,函数将字符串添加到文件的第一行

时间:2015-07-01 18:41:50

标签: powershell

您想解释一下这篇文章底部的PowerShell代码中的内容吗?

我得到了我的第一个,让我们在PowerShell中说“hello world”,它需要这些代码行。它就像一个魅力,但我不确定它是做什么的,确实。

问题从

开始
$( ,$_; Get-Content $Path -ea SilentlyContinue) | Out-File $Path

所以这就是我到目前为止所理解的。

我们创建了一个名为Insert-Content的函数。使用params(输入将作为字符串插入并将添加到$path)。

function Insert-Content {
  param ( [String]$Path )

这是函数执行/处理的内容:

process {
  $( ,$_;

我不确定这是做什么的,但我猜它会得到“输入”(|"Hello World" | Insert-Content test.txt之前的“Hello World”。

然后我们得到-ea SilentylyContinue,但它做了什么?

process {
  $( ,$_; Get-Content $Path -ea SilentlyContinue) | Out-File $Path

如果你能解释这两部分,我们将不胜感激

  

$( ,$_;
  -ea SilentylyContinue

需要/使用的代码:在文档的第一行添加一个字符串。

function Insert-Content { 
  param ( [String]$Path )
  process {
    $( ,$_;Get-Content $Path -ea SilentlyContinue) | Out-File $Path
  } 
}

"Hello World" | Insert-Content test.txt

2 个答案:

答案 0 :(得分:2)

相关的代码部分必须作为一个整体处理:

$( ,$_;Get-Content $Path -ea SilentlyContinue) | Out-File $Path

首先,正如其他人所说,-ea-ErrorAction的缩短版本。 -ErrorAction SilentlyContinue告诉cmdlet"禁止显示任何错误消息并继续执行。"请参阅Get-Help about_Common_Parameters -ShowWindow

接下来,$()是子表达式运算符。它意味着"评估括号之间的内容作为自己的命令并返回结果。"请参阅Get-Help about_Operators -ShowWindow

此子表达式为:

,$_;Get-Content $Path -ea SilentlyContinue

它包含两个语句:,$_Get-Content $Path -ea SilentlyContinue。分号只是语句标识符的末尾,用于分隔两者。

,$_;是两种复杂的部分。

$_是特殊的管道变量。它始终包含当前管道中的任何对象。有关Get-Help about_Automatic_Variables -ShowWindow的更多信息,请参阅$_(它主要用于ForEach-Object和Where-Object cmdlet,因此请查看这些内容),并Get-Help about_pipelines -ShowWindow获取更多帮助管道

这里的逗号是逗号运算符(再次参见Get-Help about_Operators -ShowWindow)。它从两侧的对象创建一个数组。例如,1,2,3创建一个包含三个元素1,2和3的数组。如果需要两个项目数组,可以说1,2

如果您想要一个项目数组怎么办?好吧,你不能说1,,因为Powershell会认为你忘记了什么。相反,你可以说,1

您可以使用-is运算符对其进行测试:

PS C:\> 1,2,3 -is [Array]
True
PS C:\> 1 -is [Array]
False
PS C:\> ,1 -is [Array]
True

为什么要创建一个项目数组?好吧,如果稍后您的代码假设该项是一个数组,它可能很有用。在早期版本的Powershell中,单个项目将缺少.Count等属性。

为了完整,是的,我相信你可以写:

$( @($_);Get-Content $Path -ea SilentlyContinue)

我认为你可以重写这个功能:

function Insert-Content { 
    param ( [String]$Path )
    process {
        #Read from pipeline
        $strings = @($_);

        #Add content of specified file to the same array
        $strings += Get-Content $Path -ea SilentlyContinue;

        #Write the whole array to the file specified at $Path
        $strings | Out-File $Path;
    }
}

因此,这会将管道中的内容添加到-Path指定的文件的开头。

在不为管道对象本身创建参数并定义它的情况下,这也是一种不太好的做法。请参阅......好吧,请参阅Get-Help "about_Functions*"下的所有主题,但主要是高级主题。这是一个高级主题。

答案 1 :(得分:2)

process {...}用于将scriptblock{...})内的代码应用于函数从管道读取的每个参数参数。

$_是包含当前对象的automatic variable,之前的comma operator $_将字符串值转换为具有单个元素的字符串数组。但这不是必需的。只需$_而不是,$_,代码就可以正常工作。

Get-Content $Path读取文件$Path的内容,并以success output stream作为字符串数组(每行作为单独的字符串)回显它。

;将两个语句,$_Get-Content $Path彼此分开。

| Out-File $Path将输出写回文件$Path

subexpression operator $()需要将文件读取与写入文件解耦。当进程已经从中读取文件时,您无法写入文件,因此子表达式可确保在开始写入之前完成读取。

基本上这整个构造

  

$( ,$_;Get-Content $Path -ea SilentlyContinue) | Out-File $Path

回显来自管道的输入(即"Hello World"),然后是文件$Path的当前内容(有效地将输入字符串预先添加到文件内容中)并将所有内容写回文件。

-ea SilentlyContinue(或-ErrorAction SilentlyContinue)会抑制$Path尚不存在时会引发的错误。