I would like to get a directory listing with -recurse but to show the sub directories right under the parent. Here is what I tried:
Get-ChildItem -Directory -Depth 3 | Select-Object Fullname
The results show first top-level directories and only then level 2 and only then level 3
Example:
C:\Users\Moshe\onedrive\pictures\35mm_Film (has no sub directories)
C:\Users\Moshe\onedrive\pictures\Camera imports
C:\Users\Moshe\onedrive\pictures\Camera Roll
and only then
C:\Users\Moshe\onedrive\pictures\Camera imports\Folder1
C:\Users\Moshe\onedrive\pictures\Camera imports\Folder2
C:\Users\Moshe\onedrive\pictures\Camera imports\Folder3
and then
C:\Users\Moshe\onedrive\pictures\Camera Roll\2014
C:\Users\Moshe\onedrive\pictures\Camera Roll\2016
I would like to get the list showing parent and right underneath its sub dir For example:
C:\Users\Moshe\onedrive\pictures\35mm_Film (has no sub directories)
C:\Users\Moshe\onedrive\pictures\Camera imports
C:\Users\Moshe\onedrive\pictures\Camera imports\Folder1
C:\Users\Moshe\onedrive\pictures\Camera imports\Folder2
C:\Users\Moshe\onedrive\pictures\Camera imports\Folder3
C:\Users\Moshe\onedrive\pictures\Camera Roll
C:\Users\Moshe\onedrive\pictures\Camera Roll\2014
C:\Users\Moshe\onedrive\pictures\Camera Roll\2016
it will also be nice to have the count of files for each directory but not crucial
For example:
C:\Users\Moshe\onedrive\pictures\35mm_Film 100
C:\Users\Moshe\onedrive\pictures\Camera imports 0 (no files in the parent)
C:\Users\Moshe\onedrive\pictures\Camera imports\Folder1 20
etc
Thanks
CodePudding user response:
To get the directories in that order you can use Sort-Object.
Example:
Get-ChildItem -Directory -recurse -Depth 3 | Select-Object Fullname | Sort-Object Fullname
This will give you the parent and their subfolders in order.
CodePudding user response:
If you want to do this without the need of sorting afterwards the solution can be a bit cumbersome, you can either use a recursive function / script block or as shown in this example, with a Stack<T>
and as optional you can use a class:
class Tree {
[int64] $Depth
[string] $Path
[int] $FileCount
hidden [IO.DirectoryInfo] $Instance
Tree ([IO.DirectoryInfo] $Directory, [int] $Depth) {
$this.Instance = $Directory
$this.Path = $Directory.FullName
$this.Depth = $Depth
$this.CountFiles()
}
[IO.DirectoryInfo[]] EnumerateDirectories() {
return $this.Instance.EnumerateDirectories()
}
[void] CountFiles() {
$this.FileCount = $this.Instance.GetFiles().Count
}
}
$stack = [Collections.Generic.Stack[Tree]]::new()
$maxDepth = 3
# initial path here
$path = 'C:\Users\Moshe\onedrive\pictures'
$stack.Push([Tree]::new($path, 0))
while($stack.Count) {
$folder = $stack.Pop()
if($folder.Depth -gt $maxDepth) {
continue
}
# this condition is to skip hidden and system folders,
# remove it if you want to show all
if(-not ($folder.Instance.Attributes -band [IO.FileAttributes]'Hidden, System')) {
$folder
}
foreach($i in $folder.EnumerateDirectories()) {
$stack.Push([Tree]::new($i, $folder.Depth 1))
}
}