【问题标题】:Create an array from get-child item list quicky in PowerShell在 PowerShell 中从 get-childitem list quickie 创建一个数组
【发布时间】:2021-07-28 22:51:41
【问题描述】:

我正在尝试缩短我的脚本并减少我使用的foreach 的数量。我有一个使用 Get-ChildItem 的项目列表,我想拆分每个文件名并从总列表中创建一个数组。

示例目录:

\\path\file1.name1.example1.jpg
\\path\file2.name2.example2.jpg
\\path\file3.name3.example3.jpg

期望的结果:

file1
file2
file3

当前脚本:

#get-child item of all files in hte path
$files = get-childitem "\\Path\" -Recurse
    $filenames = $files.Name.Split(".")[0]

也试过了:

#get-child item of all files in hte path
$files = get-childitem "\\Path\" -Recurse
    $filenames =  @($files.Name).Split(".")[0]

当然,上面只为 $files 中的每个项目生成 file1 而不是 split 的第 0 部分。有没有一种方法可以一次性获得所需的结果,而无需向split 每次一个文件添加额外的foreach 操作?

【问题讨论】:

  • "[...] 并减少我使用的foreach 的数量" - 为什么?
  • 主要是为了学习新的命令和功能。我还发现,在没有大量嵌套的情况下,我更容易将脚本交给我的同事根据他们自己的需要进行修改。您在下面的回答很有意义,我认为集成 foreach-object 是可行的方法,而不是依赖于 foreach 循环。非常感谢,一如既往地很有帮助。
  • 作为强迫自己更好地利用管道语义(和“尝试新事物”)的练习,它非常有意义 - foreach(...){} 非常适合已经物化的集合,但管道为王当涉及到“流式传输”数据时:-)

标签: arrays powershell split


【解决方案1】:

您可以将大多数本机运算符应用于集合,因此如果我们只是将您的字符串操作例程重写为在单个运算符调用中完成相同的操作 - 例如-replace for示例:

$fileNames = (Get-ChildItem "\\Path\" -Recurse).Name -replace '\..*$'

正则表达式 \..*$ 将匹配第一个文字 . 并将其与之后的所有内容一起删除。


虽然$collection -replace $pattern 通常比$collection |ForEach-Object {$_ -replace $pattern} 快,但这实际上可能不是最有效的方法 - 将Get-ChildItem ... 分组到() 意味着我们正在等待 @ 987654330@ 完成枚举所有文件,然后我们才能开始对结果数组进行操作。

如果您希望第一个结果尽可能快,请利用管道和ForEach-Object

Get-ChildItem -Path "\\Path\" -Recurse |ForEach-Object {
  $_.Split('.')[0]
}

foreach(...){} 循环语句不同,PowerShell 管道中的命令连续执行,这意味着ForEach-Object 可以在Get-ChildItem 的第一个输出项上开始操作早于Get-ChildItem完成。

我的建议:尝试两者并衡量差异(使用 Measure-Command 或更花哨的东西,例如 PSProfiler) - 结果可能会有很大差异,具体取决于您的输入和您的结构对结果数据的后续工作

【讨论】:

    猜你喜欢
    • 2021-08-05
    • 1970-01-01
    • 2011-02-22
    • 1970-01-01
    • 2013-06-06
    • 1970-01-01
    • 2019-02-17
    • 2018-01-09
    • 1970-01-01
    相关资源
    最近更新 更多