【问题标题】:Is it possible to use a ternary operator inside a pipeline?是否可以在管道内使用三元运算符?
【发布时间】:2020-02-20 13:50:52
【问题描述】:

我希望根据 $debug 的布尔值将文件和文件夹属性发送到 csv 文件或屏幕。我试图通过在以下管道的末尾包含一个三元运算符来实现这一点:

Get-ChildItem $directory -Recurse -File |
    Select-Object @{name='Folder_Name';expression={$($_.directoryname)}},
                  @{name='File_type';expression={$($_.extension)}},
                  @{name='File_name';expression={$($_.name)}},
                  @{name='File_size_bytes';expression={$($_.length)}},
                  @{name='Creation_datetime';expression={$($_.creationtime)}},
                  @{name='Last_update_datetime';expression={$($_.lastwritetime)}},
                  @{name='Last_read_datetime';expression={$($_.lastaccesstime)}} |
                  (&{if ($debug) {Write-Host} else {Export-Csv -path $outpath -NoTypeInformation -force -Delimiter ';'}})

这是一种不好的方法,推荐哪种方法?

【问题讨论】:

  • 使用Write-Host 直接将内容发送到屏幕,而不是“stdout”。那将使用Write-Output。此外,除了换行符之外,您不会向屏幕发送任何内容。 ///// 最重要的是,Expressions are only allowed as the first element of a pipeline. 所以你的最后一行意味着代码永远不会运行。
  • 是否有理由不简单地保存到 $Var 然后决定将输出发送到哪里?
  • 谢谢! [grin] 一种想法是将它放入一个接受顶部目录作为参数的函数中,添加您需要的任何其他参数,将所有信息收集到一个 $Var 中,然后发送该 $Var给来电者。让调用者决定如何使用该信息。这是“工具与控制器”的想法。
  • 另一个想法是将管道的输出保存到 $Var。然后根据需要使用它。
  • 第二个更简单,第一个更灵活。如果您已经编写了高级功能并且对它们感到满意,那么第一个就是要走的路。我可能会从第二个开始,寿。 [咧嘴]

标签: powershell pipe pipeline ternary-operator


【解决方案1】:

这会做你想要的。但是,这是处理问题的一种非常奇怪的方法。它很慢,因为它为每个项目执行文件写入或为每个项目执行屏幕写入(如果已启用)。保存到 $Var 然后写入文件和/或屏幕会快得多。 [咧嘴一笑]

此代码将您的最后一行扩展为带有ifForEach-Object 调用,以测试输出目标。它还将-ErrorAction 添加到Get-ChildItem 调用以处理“无法访问的文件”错误。

它还删除了expression = 行中不需要的$()

$directory = $env:TEMP
$outpath = "$env:TEMP\GustavRasmussen.csv"

# uncomment the 2nd line to test the negative
$ToScreen = $True
#$ToScreen = $False

Get-ChildItem $directory -Recurse -File -ErrorAction SilentlyContinue |
    Select-Object @{name='Folder_Name';expression={$_.directoryname}},
                  @{name='File_type';expression={$_.extension}},
                  @{name='File_name';expression={$_.name}},
                  @{name='File_size_bytes';expression={$_.length}},
                  @{name='Creation_datetime';expression={$_.creationtime}},
                  @{name='Last_update_datetime';expression={$_.lastwritetime}},
                  @{name='Last_read_datetime';expression={$_.lastaccesstime}} |
    ForEach-Object {
        if ($ToScreen)
            {
            $_
            }
            else
            {
            Export-Csv -InputObject $_ -path $outpath -NoTypeInformation -force -Delimiter ';' -Append
            }
        }

CSV 的第一三行 ...

"Folder_Name";"File_type";"File_name";"File_size_bytes";"Creation_datetime";"Last_update_datetime";"Last_read_datetime"
"C:\Temp";".tmp";"DELCD3A.tmp";"861968";"2019-07-13 11:43:18 PM";"2019-07-13 11:42:36 PM";"2019-07-13 11:43:18 PM"
"C:\Temp";".txt";"FXSAPIDebugLogFile.txt";"0";"2015-11-03 6:54:02 PM";"2015-11-03 6:54:02 PM";"2015-11-03 6:54:02 PM"
"C:\Temp";".log";"Genre-List_2019-10-01.log";"178";"2019-10-01 12:33:47 PM";"2019-10-01 12:33:47 PM";"2019-10-01 12:33:47 PM"

屏幕输出的第一项三项...

Folder_Name          : C:\Temp
File_type            : .tmp
File_name            : DELCD3A.tmp
File_size_bytes      : 861968
Creation_datetime    : 2019-07-13 11:43:18 PM
Last_update_datetime : 2019-07-13 11:42:36 PM
Last_read_datetime   : 2019-07-13 11:43:18 PM

Folder_Name          : C:\Temp
File_type            : .txt
File_name            : FXSAPIDebugLogFile.txt
File_size_bytes      : 0
Creation_datetime    : 2015-11-03 6:54:02 PM
Last_update_datetime : 2015-11-03 6:54:02 PM
Last_read_datetime   : 2015-11-03 6:54:02 PM

Folder_Name          : C:\Temp
File_type            : .log
File_name            : Genre-List_2019-10-01.log
File_size_bytes      : 178
Creation_datetime    : 2019-10-01 12:33:47 PM
Last_update_datetime : 2019-10-01 12:33:47 PM
Last_read_datetime   : 2019-10-01 12:33:47 PM

【讨论】:

  • 不是一种“奇怪的方式”,这是一种 PowerShell 方式,在内存使用方面效率最高,可以 在某些(实际)场景中甚至更快,例如当您的物理内存不足或输入流很慢时(例如远程目录),请参阅:Advocating native PowerShell
  • @iRon - 你和我似乎在“奇怪的方式”上有所不同。对我来说更好的方法是最简单,最直接的方法......而且 - 对我来说 - 它是通过积累数据然后输出它来实现的。从我的角度来看,逐行写入文件效率非常低,并且是一个糟糕的设计选择除非需要。 ///// 然而,世界是一个多变的地方,如果我们都同意一切,那就太无聊了。 [咧嘴]
猜你喜欢
  • 2019-10-08
  • 2016-10-04
  • 2021-10-06
  • 2021-12-12
  • 1970-01-01
  • 2022-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多