【问题标题】:powershell outoput to a text file [duplicate]powershell输出到文本文件[重复]
【发布时间】:2020-07-02 21:18:42
【问题描述】:

当使用 Write-Host 写入控制台时,此 PowerShell 函数完全符合我的要求,我知道它会执行一些默认格式设置。但是,我找不到任何方法将完全相同的输出保存到文本文件中。

这是我的功能:

function Get-FileHashInfo
{

Param($mydir)

    foreach ($item in Get-ChildItem -recurse -file $mydir -force) 
    {
        $mypath = [string]$item.directory + "\" + [string]$item.name
        $myhash = Get-FileHash -Path $mypath
        Write-Host $myhash.hash $item.name $item.directory
    }
}

这是我的控制台输出:

F887266A20CAA2E44E63F1B4E26218FFD4D3541C7A7100ED9FBF3A45F03066A7 a.txt C:\data\tmp
6D21DED17244347CE2C02A96D5F81CED1CAB82343E26D7E3C57A00F0971B58C2 b.txt C:\data\tmp
2732A420088BBACD56DEB0E19D4EF5A28FA20F11B403ED3134EFDC0CC1EA0EC6 c.txt C:\data\tmp\subdir

我只需要将这些行写入与控制台上显示的完全相同的文本文件。然而,无论我尝试什么,我最终都会在输出文件中得到很多额外的数据,格式混乱,或者文本文件中什么都没有。

【问题讨论】:

  • 简而言之:Write-Host is typically the wrong tool to use,除非意图是仅写入显示器,绕过成功输出流,并且能够将输出发送到其他命令,将其捕获在变量中,将其重定向到文件。要输出一个值,请单独使用它;例如,$value 而不是 Write-Host $value(或使用 Write-Output $value,尽管很少需要)。另见:stackoverflow.com/a/50416448/45375的底部

标签: powershell text file-io


【解决方案1】:

正如@mklement0 在 cmets 中指出的那样,Write-Host 不是正确的工具,因为它用于显示目的。

这是一个简单的替代方案,不会对您的原始代码进行太多更改:

function Get-FileHashInfo
{
    Param($mydir)

    & {
        foreach ($item in Get-ChildItem -recurse -file $mydir -force) 
        {
            $mypath = [string]$item.directory + "\" + [string]$item.name
            $myhash = Get-FileHash -Path $mypath
            "$($myhash.hash) $($item.name) $($item.directory)"
        }
    } | Out-File -FilePath ".\output.txt"
}

它将您的代码包装在一个脚本块中并将输出重定向到Out-File。此 Cmdlet 是执行标准输出重定向 > 运算符的 PowerShell 方式。它还保存其输入对象的 for-display 表示,因为它使用与控制台中相同的格式。您还可以查看Out-File: Using PowerShell to Redirect Output to File 以了解Out-File 的作用。

您也不需要在此处使用Write-Output,因为由自身 提供字符串已经足以将其通过管道传递到Out-File。您可以通过在上面的 sn-p 中使用 Write-Output "$($myhash.hash) $($item.name) $($item.directory)" 来测试它,并注意它做同样的事情。

此外,要调用脚本块,您需要使用 Call operator &,在 About Operators 中有更详细的说明。如果您不使用它,您最终会将foreach 循环代码块写入文件。


更新

正如 @mklement0 在 cmets 中有用的建议,从函数中删除 Out-File 并将其沿管道传递给 Get-FileHashInfo 是一个更好的主意。我写前面的例子只是为了快速演示,但下面的 sn-p 是一种更好的方法。它也不再需要使用脚本块,但演示如何将它与管道结合使用无论如何都有助于学习目的:)。

function Get-FileHashInfo
{
    Param($mydir)

    foreach ($item in Get-ChildItem -recurse -file $mydir -force) 
    {
        $mypath = [string]$item.directory + "\" + [string]$item.name
        $myhash = Get-FileHash -Path $mypath
        "$($myhash.hash) $($item.name) $($item.directory)"
    }    
}

Get-FileHashInfo -mydir "C:\test" | Out-File -FilePath ".\output.txt"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-18
    • 1970-01-01
    • 2013-01-22
    • 1970-01-01
    • 2019-03-17
    相关资源
    最近更新 更多