Powershell 将类的输出写入文本文件会添加空行
我创建了一个类来收集脚本中的一些数据,但不确定这是否是正确的使用方法。当我将类输出到文本文件时,它每次写入该文件时都会添加2个空行。有没有办法去掉这个Powershell 将类的输出写入文本文件会添加空行,powershell,Powershell,我创建了一个类来收集脚本中的一些数据,但不确定这是否是正确的使用方法。当我将类输出到文本文件时,它每次写入该文件时都会添加2个空行。有没有办法去掉这个 [int] $numOut = 0 [int] $numIn = 0 [int] $numNone = 0 [int] $numCPE = 0 [int] $numSQR = 0 [int] $numEGX = 0 [int] $numCQA = 0 代码的各个部分都是这样做的,这些是对这些变量进行操作的唯一类型 它像这样写入文件: area
[int] $numOut = 0
[int] $numIn = 0
[int] $numNone = 0
[int] $numCPE = 0
[int] $numSQR = 0
[int] $numEGX = 0
[int] $numCQA = 0
代码的各个部分都是这样做的,这些是对这些变量进行操作的唯一类型
它像这样写入文件:
arealhobo 10/24/2020 19:47:24 1 0 1 1 1 0 1
arealhobo 10/24/2020 19:50:37 1 0 1 1 1 0 1
arealhobo 10/24/2020 19:53:15 1 0 1 1 1 0 1
可以先替换换行符:
(write-output $logging | Format-Table -AutoSize -HideTableHeaders | Out-string) -replace "\n","" >> $CWD\log.txt
您还可以实现一个方法来处理向文件的输出。这里有一个例子
class Logging {
[string]$DateTime
[string]$User
[string]$numOut
[string]$numIn
[string]$numNone
[string]$numCPE
[string]$numSQR
[string]$numEGX
[string]$numCQA
[string]$total
Log($file){
$this | Export-Csv -Path $file -Delimiter "`t" -Append -NoTypeInformation
}
}
$Logging = [Logging]::new()
$Logging.DateTime = Get-Date
$Logging.User = $env:username
$logging.NumOut = $numOut
$logging.NumIn = $numIn
$logging.NumNone = $numNone
$logging.NumCPE = $numCPE
$logging.NumSQR = $numSQR
$logging.NumEGX = $numEGX
$logging.NumCQA = $numCQA
$logging.Total = $total
现在您只需调用$logging.log(“path\to\logfile”)
指定写入位置
$Logging.log("c:\Some\Path\logging.log")
注意:下面描述的场景可能与OP不匹配。如果您在使用
>
附加到Windows PowerShell中预先存在的文件后发现文件内容按如下方式打印到控制台,则答案可能仍然很有趣;请注意额外的间距和额外的空行:
为了避免您的问题,这很可能是由于输出文件中由
>
产生的不同字符编码的意外混合造成的,您有两个选项:
- 如果您确实知道输出文件中预先存在的内容所使用的字符编码,请通过
参数使用并匹配该编码:-encoding
/>
实际上就像调用Out File
/Out File-Append
,只是您无法控制字符编码
- 在不太可能的情况下,如果您不知道先前存在的字符编码,您可以使用自动匹配的,这与
/>
Out File-Append不同,但这需要额外的工作:
- 需要预先进行额外调用,以提供
(和>
/>
)隐式提供的格式;如果没有它,输出文件
(和添加内容
)将对输出对象应用简单的设置内容
字符串化,对于通过.ToString()
cmdlet输出的对象,这些对象只会产生无用的表示,即它们的类型名称(例如,格式-*
):Microsoft.PowerShell.Commands.Internal.Format.FormatStartData
- 需要预先进行额外调用,以提供
假设您使用的是Windows PowerShell而不是PowerShell[Core]v6+[1]: 最有可能的原因(解释与您问题中的输出不完全匹配,但我怀疑这是一个发布工件):
- 您有一个先前存在的带有单字节字符编码的
文件[2],很可能是基于系统活动ANSI代码页的传统编码,也可能是UTF-8编码文件(有或没有BOM)log.txt
- 当您在内容中添加
>时,PowerShell盲目地将其默认字符编码用于
/
,在Windows PowerShell[1]中它是“Unicode”(UTF-16LE),实际上是一种双字节编码[2](但从技术上讲不是这样)这些重定向操作符是>
的别名输出文件[-Append]
NUL
字节作为其2字节表示形式中的第二个字节,读取文件字节会在每个原始字符后看到一个额外的NUL
(“`0”
)字符
在Windows[3]上,当您使用Get content
将文件内容打印到控制台时,这有两种效果:
- 在ASCII范围字符之间插入看似空格的字符,因此,例如,
打印为foo
——实际上,这些是额外的fo
字符NUL
- 在每行之后插入一个额外的(显然)空行,这是PowerShell交替接受不同换行样式(CRLF、LF、CR)的副作用:
- 由于额外的
s,原始CRLF序列(NUL
)被读取为“`r`n”
,这导致PowerShell将“`r`0`n`0”
和“`r”
分别视为换行符(换行符),从而产生额外的行“`n”
- 请注意,额外的行实际上包含一个
,随后的行以NUL
开头(从NUL
开始的尾随行),因此在被误解的行中,除第一行外,所有行似乎都以空格开头“`n”
- 由于额外的
[1] PowerShell[Core]v6+现在在所有cmdlet中一致默认为无BOM的UTF-8。而
>
(Out File-Append
)仍然与现有编码不匹配,UTF-8文件的流行使问题更小。有关PowerShell中字符编码的详细信息,请参阅
[2] 严格来说,and是可变长度编码,因为UTF-8中的每个字节不一定都是自己的字符(仅适用于ASCII范围内的字符),同样,某些(外来)字符需要UTF-16中的两个2字节序列。然而,可以公平地说UTF-8/UTF-16是基于单/双字节的
[3] 在类Unix平台(Linux、macOS)上,您甚至可能在打印到终端时没有注意到问题,因为他们的终端仿真器通常忽略NUL
s,并且由于只使用LF(“`n”
)
class Logging {
[string]$DateTime
[string]$User
[string]$numOut
[string]$numIn
[string]$numNone
[string]$numCPE
[string]$numSQR
[string]$numEGX
[string]$numCQA
[string]$total
Log($file){
$this | Export-Csv -Path $file -Delimiter "`t" -Append -NoTypeInformation
}
}
$Logging = [Logging]::new()
$Logging.DateTime = Get-Date
$Logging.User = $env:username
$logging.NumOut = $numOut
$logging.NumIn = $numIn
$logging.NumNone = $numNone
$logging.NumCPE = $numCPE
$logging.NumSQR = $numSQR
$logging.NumEGX = $numEGX
$logging.NumCQA = $numCQA
$logging.Total = $total
$Logging.log("c:\Some\Path\logging.log")
# Using UTF-8 in this example.
$logging | Format-Table -AutoSize -HideTableHeaders |
Out-File -Append -Encoding Utf8 $CWD\log.txt
# Add-Content, unlike >>, matches the character encoding of the existing file.
# Since Add-Content, unlike > / >> / Out-File, uses simple .ToString()
# stringification you first need a call to `Out-String`, which provides
# the same formatting that > / >> / Out-File implicitly does.
$logging | Format-Table -AutoSize -HideTableHeaders |
Out-String -Stream | Add-Content $CWD\log.txt