I use get-childitem to get files from directory structure.
Get-ChildItem $path -Recurse -include *.jpg,*.png | select-object Directory, BaseName, Extension
I get an array of objects with properties Directory, BaseName, Extension.
Like:
Directory BaseName Extension
C:\dir1\dir2\dir3\dir4 file txt
I wan't to break directory structure into multiple properties inside same array - each subdirectory level it's own property.
The end result properties should be (I can remove c:\ earlier in script):
dir1 dir2 dir3 dir4 Basename Extension
dir1 dir2 dir3 dir4 file txt
I used to export that to csv and import it back with delimiter to another array and than rebuilding the original array, but I think there must be an easier way!
CodePudding user response:
Here is a possible approach:
$path = 'C:\test'
$maxDepth = 0
Set-Location $path # Set base path for Resolve-Path -Relative
# Get all files and splits their directory paths
$tempResult = Get-ChildItem $path -Recurse -include *.jpg,*.png | ForEach-Object {
# Make directory path relative to $path
$relPath = Resolve-Path $_.Directory -Relative
# Create an array of directory path components, skipping the first '.' directory
$dirNames = $relPath -replace '^\.\\' -split '\\|/'
# Remember maximum directory depth
$maxDepth = [Math]::Max( $dirNames.Count, $maxDepth )
# Implicit output that PowerShell adds to $tempResult
[PSCustomObject]@{
dirNames = $dirNames
fileInfo = $_ | Select-Object BaseName, Extension
}
}
# Process $tempResult to add directory properties and file name properties
$finalResult = $tempResult.ForEach{
$outProps = [ordered] @{}
# Add directory properties
for( $i = 0; $i -lt $maxDepth; $i ) {
$outProps[ "Dir$i" ] = if( $i -lt $_.dirNames.Count ) { $_.dirNames[ $i ] } else { $null }
}
# Add all fileInfo properties
$_.fileInfo.PSObject.Properties.ForEach{ $outProps[ $_.Name ] = $_.Value }
# Implicit output that PowerShell adds to $finalResult
[PSCustomObject] $outProps
}
$finalResult # Output to console
This is done in two passes to ensure all output elements have the same number of directory properties:
- Iterate over all files and split their directory paths. Determine maximum directory depth (number of directory properties).
- Iterate over the intermediate result to create the desired objects consisting of directory properties and file name properties. This is done by first adding the properties to an ordered hashtable and then converting that hashtable to a
PSCustomObject
. This is easier and more efficient than usingAdd-Member
.
Test input:
C:\test
\subdir1
file1.png
file2.jpg
\subdir2
\subdir3
file3.jpg
Output:
Dir0 Dir1 BaseName Extension
---- ---- -------- ---------
subdir1 file1 .png
subdir1 file2 .jpg
subdir2 subdir3 file3 .jpg