Reputation: 225
I have the following powershell script that renames files from one location to another with a sequential filename. Ultimately, these file changes need to be mapped, as in original - new. Currently, I just have a Write-Host cmdlet and I just copy the cmd windows output into a txt file then run through a python script I wrote to spit out the original and renamed files into an excel file. I was wondering if there was an easier way to do this in the initial ps script. Even something tab delimited would be easily copy-pasteable into an excel file.
Set-Location -Path "C:\Users\mmcintyre\Desktop\grail_new"
$destLoc = "C:\Users\mmcintyre\Desktop\renamed"
$countRef = [ref] 0
Get-ChildItem -Filter *.pdf -Recurse |
Copy-Item -WhatIf -Destination { '{0}\{1}.pdf' -f $destLoc,++$countRef.Value }
Any help would be greatly appreciated.
Edit: I am currently using PS 2.0.
Upvotes: 1
Views: 444
Reputation: 437698
The following outputting old-name/new-name pairs to a TSV file in addition to the copy operation (PSv3+ syntax):
$countRef = [ref] 0
Get-ChildItem -Filter *.pdf -Recurse | ForEach-Object {
$newFullName = '{0}\{1}.pdf' -f $destLoc, ++$countRef.Value
Copy-Item -WhatIf -LiteralPath $_.FullName -Destination $newFullName
[pscustomobject] @{
Old = $_.FullName
New = $newFullName
}
} | Export-Csv -Delimiter "`t" NameMappings.tsv
This creates a TSV (tab-separated values) file with columns named Old
and New
that contain the old and new full filenames, respectively.
PSv2: The [pscustomobject] @{ ... }
syntactic sugar for creating custom objects from hashtables is not available in v2, so New-Object
must be used:
$countRef = [ref] 0
Get-ChildItem -Filter *.pdf -Recurse | ForEach-Object {
$newFullName = '{0}\{1}.pdf' -f $destLoc, ++$countRef.Value
Copy-Item -WhatIf -LiteralPath $_.FullName -Destination $newFullName
New-Object PSCustomObject -Property @{
Old = $_.FullName
New = $newFullName
}
} | Export-Csv -Delimiter "`t" NameMappings.tsv
Caveat: -Property
accepts a hashtable[1]
, which means that its key ordering is not guaranteed, so the ordering of properties of the resulting object will typically not reflect the input order - in this case it just happens to do so.
If the resulting property order is undesired, you have two options:
Slow, but convenient: insert a Select-Object
call with the properties in the desired order (e.g., Select-Object Old, New
).
More cumbersome: Construct the object empty at first New-Object PSCustomObject
, and then attach properties one by one in the desired order with individual Add-Member
calls.
[1] The PSv3+ [pscustomobject] @{ ... }
syntax is seemingly also hashtable-based, but it is parsed in a way that preserves the key order; i.e., as if you had implicitly used [ordered] @{ ... }
.
Upvotes: 2