【问题标题】:Recursing through directories: child objects showing up blank?通过目录递归:子对象显示为空白?
【发布时间】:2016-12-29 08:36:05
【问题描述】:

我正在构建一个脚本,用于递归遍历文件树,构建一个对象来表示该树,并以 JSON 格式打印出来。但是,由于某种原因,当我尝试打印子对象时,它们显示为空白。这是我到目前为止的代码:

$dir = "c:\dell"

# Top-level object to hold the directory tree
$obj = @{}

function recurse($dir, [ref]$obj) {

    write-host "recursing into $dir"

    # Object to hold this subdir & children
    $thisobj = @{}

    # List the files & folders in this directory
    $folders = Get-ChildItem $dir | Where-Object { $_.PSIsContainer -eq $true  }
    $files   = Get-ChildItem $dir | Where-Object { $_.PSIsContainer -eq $false }

    #write-host $folders

    # Iterate through the subdirs in this directory
    foreach ($f in $folders) {
        # Recurse into this subdir
        recurse $f.fullname ([ref]$thisobj)
    }

    # Iterate through the files in this directory and add them to 
    foreach ($f in $files) {
        write-host " - adding file to thisobj: $f"
        $thisobj | add-member -MemberType NoteProperty -Name $f -value 10
    }

    # Print out this subtree
    "$dir thisobj: "
    $thisobj | convertto-json -depth 100

    # Add this subtree to parent obj
    $obj | Add-Member -MemberType NoteProperty -name $dir -value $thisobj

    write-host "finished processing $dir"

}

# Initial recursion
recurse $dir ([ref]$obj)

write-host "final obj:"
$obj | ConvertTo-Json -depth 100

这是我试图让最终输出看起来像的样子:

{
    "updatepackage": {
        "log": {
            "DELLMUP.log": 5632
        }
        "New Text Document.txt": 0
    }
    "list.csv": 588
}

【问题讨论】:

  • 你能提供一个你想要从这个过程中得到的 JSON 的例子吗?我有一种感觉,你在这里所做的可能比需要的代码多。
  • 可能,但我找不到更好的方法。我已将示例输出添加到问题中。
  • 你的脚本应该实现什么?
  • [ref]$obj -> $obj, [ref]$thisobj -> $thisobj,但我个人会重写 recurse 以返回对象,而不是修改参数传递的对象。
  • 我有一种感觉 $Json = gci -recurse | Where-Object {$_.PSIsContainer -eq $false} | select Name, Length | ConvertTo-Json 在您选择所需属性的地方可以更快、更干净地完成您想要的操作...

标签: json powershell recursion


【解决方案1】:

我认为,您最好重写recurse 以返回表示目录的对象,而不是修改参数传递的对象:

function recurse {
    param($Dir)

    Get-ChildItem -LiteralPath $Dir |
    ForEach-Object {
        $Obj = [ordered]@{}
    } {
        $Obj.Add($_.PSChildName, $(
            if($_.PSIsContainer) {
                recurse $_.PSPath
            } else {
                $_.Length
            }
        ))
    } {
        $Obj
    }
}

recurse c:\dell | ConvertTo-Json -Depth 100

【讨论】:

  • 产生我想要的输出。你能解释一下你如何使用 ForEach-Object 的语法吗?
  • @wmassingham 1..3 | ForEach-Object { 'Begin' } { "Process $_" } { 'End' } 我只使用所有三个(BeginProcessEnd)块,而只使用 Process 块。
猜你喜欢
  • 1970-01-01
  • 2015-11-16
  • 2019-01-19
  • 1970-01-01
  • 2011-05-05
  • 2020-08-03
  • 1970-01-01
  • 2019-01-22
  • 1970-01-01
相关资源
最近更新 更多