Home > other >  How to merge two tables that have same table structure? in PowerShell
How to merge two tables that have same table structure? in PowerShell

Time:06-18

In the following script, the outputs are displayed as two separate tables (each with two columns). How can I display both tables in a table with three columns?

# Create a hash table for File QTY
$Qty = @{}

# Create a hash table for file size
$Size = @{}

# Import all files into one $Files
$Files = Get-ChildItem 'D:\' -Filter *.* -Recurse -File

# Create a loop to check $file in $Files
foreach ($file in $Files) {
    # Count files based on Extension 
    $Qty[$file.Extension]  = 1
    # Summarize file sizes based on their format
    $Size[$file.Extension]  = $file.Length / 1GB
}

# Show File QTY table
$Qty 
# Show file size table
$Size

Like this:

Type    Size    Qyt
-----   -----   -----   
.jpg    10 GB   10000
.png    30 GB   30000
.tif    40 GB   40000

CodePudding user response:

Extract the keys (the file extensions) from one table and use that as a "driver" to construct a new set of objects with the size and quantity values from the tables:

$Qty.psbase.Keys |Select-Object @{Name='Type';Expression={$_}},@{Name='Size';Expression={$Size[$_]}},@{Name='Qty'; Expression={$Qty[$_]}}

CodePudding user response:

While you already got an answer that does exactly what you asked for, I would take a different approach, that doesn't need hashtables:

# Import all files into one $Files
$Files = Get-ChildItem 'D:\' -Filter *.* -Recurse -File

# Group files by extension and collect the per-extension information
$Files | Group-Object -Property Extension |
    Select-Object @{ n = 'Type'; e = 'Name' },
                  @{ n = 'Size'; e = { '{0:0.00} GB' -f (($_.Group | Measure-Object Length -Sum).Sum / 1GB) } },
                  @{ n = 'Qty';  e = 'Count' }

Output is like:

Type    Size       Qty
-----   -----      -----   
.jpg    10.23 GB   10000
.png    30.07 GB   30000
.tif    40.52 GB   40000
  • Group-Object produces an object per unique file extension. It has a property Count, which is the number of grouped items, so we can use that directly. Its property Name contains the file extension. Its Group property contains all FileInfo objects from Get-ChildItem that have the same extension.
  • Using Select-Object we rename the Name property to Type and rename the Count property to Qty. We still need to calculate the total size per file type, which is done using Measure-Object -Sum. Using the format operator -f we pretty-print the result.
  • Replace {0:0.00} by {0:0} to remove the fractional digits from the Size column.
  • The syntax @{ n = ...; e = ... } is shortcut for @{ name = ...; expression = ... } to create a calculated property.
  • You may defer the formatting of the Size column to Format-Table, to be able to do additional processing based on the numeric value, e. g. sorting:
    $files | Group-Object -Property Extension |
        Select-Object @{ n = 'Type'; e = 'Name' },
                      @{ n = 'Size'; e = { ($_.Group | Measure-Object Length -Sum).Sum } },
                      @{ n = 'Qty';  e = 'Count' } |
        Sort-Object Size -Descending |
        Format-Table 'Type', @{ n = 'Size'; e = { '{0:0} GB' -f ($_.Size / 1GB) } }, 'Qty'
    
  • Related