Search code examples
powershellrelative-path

How can I modify the output of Select-Object in PowerShell?


I can get file hashes using this code:

Get-ChildItem -Path "E:\Test 1" -Recurse -File | Get-FileHash -Algorithm MD5 | Select-Object Hash,Path | Format-Table -HideTableHeaders | Out-File -encoding ASCII -filepath "file.md5"

Which gives me exactly what I want, except I need relative paths (relative to the path for Get-ChilItem, e. g. relative to E:\Test 1).

I know I can resolve relative paths with this:

Get-ChildItem -path "E:\Test 1\*.*" -Recurse -File | Split-Path -NoQualifier

This works fine.

But how do I manipulate Split-Path -NoQualifier part to the Path output in the first code snippet? Preferably in a single line of code if possible.

EDIT:

Just wanted to clarify looking to output path RELATIVE to INPUT PATH (i.e. "E:\Test 1").

Bottom line looking to mimic output of Linux output from: find . -type f -exec md5sum {} + which results in something like this:

md5hashmd5hashmd5hashmd5hashmd5h \path\to\file\file.ext

Code from user stackprotector seems to work! Thanks.


Solution

  • You can modify each element after Select-Object with ForEach-Object. To get paths relative to what you input to Get-ChildItem, you have to preserve that somehow, e. g. by using a variable ($basepath). This is how you can generate your relative path:

    ForEach-Object {$_.Path = ($_.Path -replace [regex]::Escape($basepath), '').trimstart('\'); $_}
    

    So in total:

    $basepath = 'E:\Test 1'
    Get-ChildItem -Path $basepath -Recurse -File | Get-FileHash -Algorithm MD5 | Select-Object Hash,Path | ForEach-Object {$_.Path = ($_.Path -replace [regex]::Escape($basepath), '').trimstart('\'); $_} | Format-Table -HideTableHeaders | Out-File -encoding ASCII -filepath "file.md5"