避免写入输出中的换行符

ith*_*yme 16 powershell

我想从日志文件中收集脚本的所有输出,并且必须使用write-output instaed of write-host.

Write-Output "Server:" $a 好像

Server:
foo
.

我是否真的必须写信
write-output $("sfdghk:" + $a)才能获得Server:Foo

谢谢-jt

小智 14

发现在互联网上的某个地方:

Write-Output "Server: $($a)"
Run Code Online (Sandbox Code Playgroud)

在我的代码中工作得很好.

  • 对于这个例子,`$(...)`结构是多余的,因为它表示将括号内的所有内容都视为脚本而不是文本.由于`$ a`已经被解释并插入引用的字符串中,因此不需要添加包装器.`Write-Output'服务器:$ a"`...将正常工作.当您尝试访问变量的方法或属性时,请使用包装器`$()`.`$ a ="我喜欢鸡蛋." 写输出"字符数:$($ a.length)"`将打印出`我喜欢eggs..length`而没有`$(...)`包装器. (4认同)

JPB*_*anc 7

9个小时......我开始回答.

在Powershell中,你操纵的一切都是一个对象.

所以"Server:"是一个对象,$ a是一个对象

PS> "server :".gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object
Run Code Online (Sandbox Code Playgroud)

Write-output是一个CmdLet,它将对象放在一种列表(管道)中,供其他CmdLets或脚本使用.所以"Server:"和"foo"之间没有真正的换行符.这是控制台向您显示对象列表(数组)的方式.正如您在此处看到的:

PS> $a = "foo"
PS> (Write-Output "Server :" $a).gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array
Run Code Online (Sandbox Code Playgroud)

显然这是一个摘要,但我希望它可以让你理解.


Aar*_*sen 6

Write-Output "Server: $a"
Write-Output ("Server: {0}" -f $a)
Write-Output ("Server: " + $a)
Run Code Online (Sandbox Code Playgroud)

如果要将脚本的输出收集到日志文件中,请考虑使用Start-Transcript.它将每个命令和所有PowerShell输出记录到文件中.但是,它不记录发送到stdout的任何内容,因此,如果您使用任何遗留命令,则必须将其输出通过管道输出到Write-Host:

Start-Transcript C:\logs\mylog.txt
Write-Host "Server: " $a
ping | Write-Host
Run Code Online (Sandbox Code Playgroud)

  • PowerShell的_equivalent_到stdout是它的_success输出stream_和那里发送的东西_do_得到记录.`write-Host` _在past_中没有写入_stdout_而是直接打印到console_,这就是为什么这样的输出没有出现在成绩单中.然而,在PSv5 +中,`Write-Host` /`Out-Host`现在写入新引入的_information stream_(就像新的`Write-Information` cmdlet一样),现在_does_得到记录.您可以使用`$ null = ...`来完全抑制输出,或者,在此上下文中模拟PSv4-`Write-Host`行为,使用`$ host.ui.WriteLine()`. (2认同)

mkl*_*nt0 6

现有答案中有很好的信息,但让我尝试一个务实的总结:

  • 当打印到控制台或重定向到一个文件,Write-Output分隔多个通过每个换行参数。

  • 因此,为了生成单行输出,您必须将要输出的部分“预组装”为作为单个参数传递的单个字符串。

  • 除了抑制集合的枚举,您通常不需要Write-Output显式使用,因为 PowerShell默认发送任何未在变量中捕获或重定向到其他地方或通过管道发送到[success] 输出流(Write-Output也写入) ; 因此,就目前的情况而言,以下内容就足够了:

"Server: $a"  # what this expandable string expands to is *implicitly* output
Run Code Online (Sandbox Code Playgroud)

可能令人困惑的是Write-Hostcmdlet 的行为不同,但重要的是要注意它有不同的用途。

# IMPORTANT: Do not use Write-Host to output *data*; only use it to write
#            directly to the host (console).
PS> Write-Host "Server:"     $a    # multiple spaces used on purpose
Server: srv1
Run Code Online (Sandbox Code Playgroud)

Write-Host,与 不同Write-Output,将多个参数分别用一个空格分隔。
还有其他重要的区别,在我的这个答案中进行了总结。


鉴于问题的通用标题,让我们还讨论如何抑制尾随换行符:

  • 对于仅打印到控制台,您可以使用Write-Host -NoNewline.

  • 使用数据输出,无论是通过Write-Output、隐式输出还是来自另一个命令:

    • 将输出发送到控制台时,您无法阻止尾随换行符。

    • 不幸的是,从 Windows PowerShell v5.1 / PowerShell Core v6.0.0 开始,在通过管道向外部程序发送文本时,您无法阻止尾随换行符- 请参阅此 GitHub 问题。

    • 但是,在 PSv5+ 中,您可以通过使用或(在 PSv4- 中,您必须直接使用 .NET Framework)来防止在捕获文件中的输出时出现尾随换行符;相比之下,重定向到一个文件确实会附加一个尾随换行符。Out-File -NoNewlineSet-Content -NoNewline>

      • 警告:如果您要输出多个对象,-NoNewline不仅会抑制尾随换行符,还会抑制这些对象之间的换行符。
      • 对于之间的差异Out-File,并Set-Content当选择哪个,看到这个答案我的。

  • @not2qubit:作为独立的命令参数,您可以按原样使用 `$args[-1]`:`& { Write-Output $args[-1] } one Two`。要将其嵌入到更大的字符串中,您需要 `$(...)`: `& { Write-Output "$($args[-1])!" } 一二` - 请参阅 PowerShell 的[字符串插值规则](/sf/answers/2831219891/)。 (2认同)