gpt4 book ai didi

powershell - Powershell Out-File在文件顶部添加换行符-Out-File与Set-Content

转载 作者:行者123 更新时间:2023-12-03 23:59:27 27 4
gpt4 key购买 nike

我有以下功能:

# Find all .csproj files 
$csProjFiles = get-childitem ./ -include *.csproj -recurse

# Remove the packages.config include from the csproj files.
$csProjFiles | foreach ($_) {(get-content $_) |
select-string -pattern '<None Include="packages.config" />' -notmatch |
Out-File $_ -force}

它似乎工作正常。运行后,packages.config中的行不在文件中。

但是,在我运行之后,文件的 TOP 处还有一个额外的换行符。 (不是底部。)

我对如何到达那里感到困惑。 我该怎么办才能摆脱掉在文件顶部生成的多余换行符?

更新:

我换成了另一种方式:
$csProjFiles | foreach ($_) {$currentFile = $_; (get-content $_) | 
Where-Object {$_ -notmatch '<None Include="packages.config" />'} |
Set-Content $currentFile -force}

它可以正常工作,并且文件顶部没有多余的行。但是我不介意知道为什么最上面的示例要添加额外的行。

最佳答案

  • Out-File 和重定向运算符> / >> 接受任意输入对象,并将它们转换为字符串表示形式,就像在控制台中出现的一样-即使用PowerShell的默认输出格式-将这些字符串表示形式发送到输出文件。
    这些字符串表示形式通常具有可读性的前导和/或尾随换行符。
  • 有关更多信息,请参见 Get-Help about_Format.ps1xml
  • Set-Content 用于已为字符串或应视为字符串的输入对象
  • PowerShell在所有输入对象上调用.psobject.ToString()以获取字符串表示形式,该字符串表示形式在大多数情况下均遵循基础.NET类型的.ToString()方法。

  • 生成的表示形式通常是不同的,并且重要的是要知道何时选择哪个cmdlet /运算符。

    另外,默认字符编码与不同:
  • Out-File> / >>默认为UTF-16 LE ,PowerShell在可选Unicode参数的上下文中调用-Encoding
  • Set-Content默认为系统的旧版“ANSI”代码页(单字节扩展ASCII代码页),PowerShell将其称为Default
  • 请注意,自PSv5.1起,the docs错误地声称默认值为ASCII。[1]

  • ,请更改编码:
  • 临时更改:将 -Encoding参数Out-FileSet-Content一起使用,以显式控制输出字符的编码。
    您无法更改> / >>即席使用的编码,但请参见下文。
  • [PSv3 +] 更改默认的(请谨慎使用):使用$PSDefaultParameterValues机制(请参阅 Get-Help about_Parameters_DefaultValues ),该机制可为参数设置默认值:
  • 更改Out-File的默认编码也会将其更改为PSv5.1或更高版本 [2]中的> / >>
    例如,要将其更改为UTF-8,请使用:$PSDefaultParameterValues['Out-File:Encoding']='UTF8'
  • 请注意,在PSv5.0或更低版本中的,您无法更改使用的编码>>>
  • 如果更改Set-Content的默认值,请确保也将Add-Content的默认值也更改为:$PSDefaultParameterValues['Set-Content:Encoding'] = $PSDefaultParameterValues['Add-Content:Encoding'] ='UTF8'
  • 您还可以使用通配符模式来表示cmdlet /高级函数名称,以将默认参数值应用于该值。例如,如果使用$PSDefaultParameterValues['*:Encoding']='UTF8',则所有具有-Encoding参数的cmdlet都将默认为该值,但这是不明智的,因为在某些cmdlet中-Encoding是指输入编码。
  • 在写入文件的cmdlet中没有一个共享的前缀,可以让定位所有输出cmdlet的,但是您可以为每个动词定义一个模式:$enc = 'UTF8; $PSDefaultParameterValues += @{ 'Out-*:Encoding'=$enc; 'Set-*:Encoding'=$enc; 'Add-*:Encoding'=$enc; 'Export-*:Encoding'=$enc }
  • 警告:$PSDefaultParameterValues在全局范围内定义,因此您对其进行的任何修改都会在全局范围内生效,并影响后续命令。
    要限制对脚本/函数的作用域及其后代作用域的更改,请使用本地$PSDefaultParameterValues变量,您可以将其初始化为空的哈希表以从头开始($PSDefaultParameterValues = @{}),或者初始化为全局值的克隆($PSDefaultParameterValues = $PSDefaultParameterValues.Clone())


  • 在当前情况下,输出对象是[Microsoft.PowerShell.Commands.MatchInfo]输出的Select-String实例:
  • 使用默认格式(如Out-File一样),它们在上方输出一个空行,在下方输出两个空行(多个实例在上方和下方的一组空行之间的连续块中打印)。
  • 如果像对.psobject.ToString()一样在它们上调用Set-File,它们将只求值匹配行(假定输入是通过管道提供的,而不是通过-Path / -LiteralPath参数作为文件名),它们只评估匹配的行(没有源路径前缀)前导或尾随的空行。

  • 就是说,如果您通过管道传递给| Select-Object -ExpandProperty Line或只是| ForEach-Object Line以便仅将匹配的行显式输出为字符串,那么Out-FileSet-Content都会产生相同的结果(它们的默认编码除外)。

    附注:LotPing的观察是正确的:您似乎将foreach语句与ForEach-Object cmdlet混淆了(遗憾的是,内置别名foreach也知道该语句,引起混乱)。

    ForEach-Object cmdlet不需要为$_定义一个明确的定义:在传递给它的(暗示的-Process)脚本块中,$_自动定义为手头的输入对象。

    您对($_)(foreach)的ForEach-Object参数实际上被忽略:因为它的求值为$null:自动变量$_,当在特殊上下文之外使用时(例如管道中的脚本块),有效地求值为$null,而在其周围放了(...)则没有任何区别,因此您可以有效地传递$null,而该代码会被忽略。

    [1]确认ASCII不是默认值,如下所示:'0x{0:x}' -f $('ä' | Set-Content t.txt; $b=[System.IO.File]::ReadAllBytes("$PWD\t.txt")[0]; ri t.txt; $b)在en-US系统上产生0xe4,这是ä的Windows-1252代码点(与Unicode代码点一致,但是输出是单字节代码)。没有BOM的编码文件)。
    如果显式使用-Encoding ASCII,则将获得0x3f,即文字?的代码点,因为那是使用ASCII转换所有非ASCII字符的原因。至。

    [2] PetSerAl发现source-code location表示>>>Out-File [-Append]的有效别名,他指出重新定义Out-File也因此重新定义> / >>;同样,通过$PSDefaultParameterValuesOut-File指定默认编码也会对> / >>生效。
    Windows PowerShell v5.1是使用这种方式的最低版本。

    PetSerAl求助。

    关于powershell - Powershell Out-File在文件顶部添加换行符-Out-File与Set-Content,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42449408/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com