如何使“Tee-Object”不在 PowerShell 中添加尾随换行符?
How can I make `Tee-Object` not adding a trailing newline in PowerShell?
Tee-Object
does not have a -NoNewline
switch like many other output-to-file-cmdlets (e. g. Out-File
, Set-Content
). Under the hood、Tee-Object
使用Out-File
写入文件,默认添加尾随换行符。
由于我(当前)无法通过 -NoNewline
开关通过 Tee-Object
,是否有另一种方法我可以强制执行底层 Out-File
不会添加尾随换行符吗?查看 implementation of Out-File
,现在可能有方法,但也许有人知道一些 tricks/hacks 无论如何可以实现它?
一些约束:
- 我想在管道中使用
Tee-Object
(或替代解决方案)
- 我不想 post 处理由
Tee-Object
(或替代解决方案)生成的文件,例如再次打开它们并删除(最后一个)换行符。
复制代码:
"Test" | Tee-Object file | Out-Null
在 Windows 上,生成的文件 file
将包含 6 个字节,如以下十六进制转储所示:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII
00000000 54 65 73 74 0D 0A Test..
不幸的是,其中包含额外的字节0D 0A
a。 k.一种。 `r`n
或 Windows 中的 CR&LF。
你可以自己写一个带前缀的换行符:
function Tee-StackProtectorObject {
param(
[Parameter(Mandatory=$true, Position=1, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
[AllowNull()]
[AllowEmptyCollection()]
[psobject]
$InputObject,
[Parameter(ParameterSetName='Path', Mandatory=$true, Position=0, ValueFromPipelineByPropertyName=$true)]
[string[]]
$Path,
[Parameter(ParameterSetName='LiteralPath', Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
[Alias('PSPath')]
[string[]]
$LiteralPath
)
begin {
# Determine newline character sequence at the start (might differ across platforms)
$newLine = [Environment]::NewLine
# Prepare parameter arguments for Add-Content
$addContentParams = @{ NoNewLine = $true }
if($PSCmdlet.ParameterSetName -eq 'Path'){
$addContentParams['Path'] = $Path
}
else {
$addContentParams['LiteralPath'] = $LiteralPath
}
}
process {
# Write to file twice - first a newline, then the content without trailling newline
Add-Content -Value $newLine @addContentParams
Add-Content -Value $InputObject @addContentParams
# Write back to pipeline
Write-Output -InputObject $InputObject
}
}
请注意,与 Tee-Object
不同,上述函数处于永久“附加模式”。重构它以支持追加和覆盖留作 reader :)
的练习
Tee-Object
does not have a -NoNewline
switch like many other output-to-file-cmdlets (e. g. Out-File
, Set-Content
). Under the hood、Tee-Object
使用Out-File
写入文件,默认添加尾随换行符。
由于我(当前)无法通过 -NoNewline
开关通过 Tee-Object
,是否有另一种方法我可以强制执行底层 Out-File
不会添加尾随换行符吗?查看 implementation of Out-File
,现在可能有方法,但也许有人知道一些 tricks/hacks 无论如何可以实现它?
一些约束:
- 我想在管道中使用
Tee-Object
(或替代解决方案) - 我不想 post 处理由
Tee-Object
(或替代解决方案)生成的文件,例如再次打开它们并删除(最后一个)换行符。
复制代码:
"Test" | Tee-Object file | Out-Null
在 Windows 上,生成的文件 file
将包含 6 个字节,如以下十六进制转储所示:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII
00000000 54 65 73 74 0D 0A Test..
不幸的是,其中包含额外的字节0D 0A
a。 k.一种。 `r`n
或 Windows 中的 CR&LF。
你可以自己写一个带前缀的换行符:
function Tee-StackProtectorObject {
param(
[Parameter(Mandatory=$true, Position=1, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
[AllowNull()]
[AllowEmptyCollection()]
[psobject]
$InputObject,
[Parameter(ParameterSetName='Path', Mandatory=$true, Position=0, ValueFromPipelineByPropertyName=$true)]
[string[]]
$Path,
[Parameter(ParameterSetName='LiteralPath', Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
[Alias('PSPath')]
[string[]]
$LiteralPath
)
begin {
# Determine newline character sequence at the start (might differ across platforms)
$newLine = [Environment]::NewLine
# Prepare parameter arguments for Add-Content
$addContentParams = @{ NoNewLine = $true }
if($PSCmdlet.ParameterSetName -eq 'Path'){
$addContentParams['Path'] = $Path
}
else {
$addContentParams['LiteralPath'] = $LiteralPath
}
}
process {
# Write to file twice - first a newline, then the content without trailling newline
Add-Content -Value $newLine @addContentParams
Add-Content -Value $InputObject @addContentParams
# Write back to pipeline
Write-Output -InputObject $InputObject
}
}
请注意,与 Tee-Object
不同,上述函数处于永久“附加模式”。重构它以支持追加和覆盖留作 reader :)