【问题标题】:ForEach-Object somehow flattens returned valuesForEach-Object 以某种方式展平返回值
【发布时间】:2021-04-04 16:25:24
【问题描述】:

假设我想从文件中读取一些字符串,并且对于每个字符串我想拆分它。最后,我想得到字符串数组的数组。这是我尝试的方法:

$toArchive = "./folders.txt"
$folderList = Get-Content $toArchive | ForEach-Object { @($_.split(" ")) }

Get-Content 应该返回一个字符串数组,对于每个字符串,我希望得到另一个字符串数组。但我的folderList 不是Object[],就好像它被压扁了一样。例如,如果我的输入文件如下所示:

Docs /home/keddad/Documents/
NotDocs /home/keddad/NotDocuments/

我得到 4 个元素的数组:

Docs                                                                                                                                                                                                                                                                           
/home/keddad/Documents/                                                                                                                                                                                                                                                        
NotDocs                                                                                                                                                                                                                                                                        
/home/keddad/NotDocuments/

我在这里做错了什么?

更新:澄清一下,它肯定是 4 个字符串的数组:

PS /home/keddad/Documents/tbackup> $toArchive = "./folders.txt"
PS /home/keddad/Documents/tbackup> $folderList = Get-Content $toArchive | ForEach-Object { @($_.split(" ")) }
PS /home/keddad/Documents/tbackup> $folderList.count
4
PS /home/keddad/Documents/tbackup> $folderList
Docs
/home/keddad/Documents/
NotDocs
/home/keddad/NotDocuments/

【问题讨论】:

  • $folderlist.count 显示什么?
  • Powershell 喜欢通过展开集合来“帮助”用户。应该可以通过在拆分前添加逗号来解决。甚至可能不需要括号。 ,$_.Split(“ ") 或 ,($_.Split(“ ")
  • 我不喜欢逗号运算符,IMO 它使代码变得晦涩难懂。另一种方法是将数组放在[PSCustomObject] 中,如下所示:ForEach-Object{ [PSCustomObject]@{ value = $_.split(" ") } }。 PowerShell 永远不会弄平 [PSCustomObject]
  • @zett42,有一个冗长、概念清晰的替代方案,但它增加了开销:您可以使用, 'foo bar'.Split(" ") 而不是Write-Output -NoEnumerate 'foo bar'.Split(" ")
  • @biryulin04,注意@(...)不是数组构造函数,而是保证器,可以这么说:它收集命令的输出或表达式的 enumerated 输出 - 总是 new - [object[]] array - 即使该输出是 single 对象。因此,像@(@(1, 2) 这样的东西 not 创建一个 nested 数组;它实际上(但效率低下)与@(1, 2) 相同;要构造嵌套数组,请使用 , 的一元形式:, (1, 2) - 请参阅 this answer

标签: powershell


【解决方案1】:

你错过了array construction operator ,

(Get-Content .\folders.txt | ForEach-Object ({ ,$_.split(" ") }))

哪个会渲染

> (Get-Content .\folders.txt | ForEach-Object ({ ,$_.split(" ") })).count
2

还有,我相信你喜欢的结构,例如:

> (Get-Content .\folders.txt | ForEach-Object ({ ,$_.split(" ") }))[0]
Docs
/home/keddad/Documents/

> (Get-Content .\folders.txt | ForEach-Object ({ ,$_.split(" ") }))[0][0]
Docs

> (Get-Content .\folders.txt | ForEach-Object ({ ,$_.split(" ") }))[0][1]
/home/keddad/Documents/

或整体可视化为 JSON:

> (Get-Content .\folders.txt | ForEach-Object ({ ,$_.split(" ") })) | ConvertTo-Json

[
    {
        "value":  [
                      "Docs",
                      "/home/keddad/Documents/"
                  ],
        "Count":  2
    },
    {
        "value":  [
                      "NotDocs",
                      "/home/keddad/NotDocuments/"
                  ],
        "Count":  2
    }
]

【讨论】:

    【解决方案2】:
    猜你喜欢
    • 2014-09-24
    • 1970-01-01
    • 1970-01-01
    • 2017-05-21
    • 1970-01-01
    • 1970-01-01
    • 2021-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多