Reputation: 45
I have several folder (35 to be exact), each folder contains 10-12 sub-folders and each sub folder about 20 files.
I want to prefix each file with the name of the sub-folder but the only command I found is for renaming only one folder at a time :
dir | Rename-Item -NewName {$_.Directory.Name + " - " + $_.Name}
Is there a way to loop through all the folder ? (I'm not used to Powershell)
Upvotes: 1
Views: 543
Reputation: 16096
Yes, there is, and it is detailed in the PowerShell Help files. That is what the -recurse parameter is for.
# Get specifics for a module, cmdlet, or function
(Get-Command -Name Get-ChildItem).Parameters
(Get-Command -Name Get-ChildItem).Parameters.Keys|clip
# Results
<#
Path
LiteralPath
Filter
Include
Exclude
Recurse
Depth
Force
Name
Verbose
Debug
ErrorAction
WarningAction
InformationAction
ErrorVariable
WarningVariable
InformationVariable
OutVariable
OutBuffer
PipelineVariable
UseTransaction
Attributes
Directory
File
Hidden
ReadOnly
System
#>
Get-help -Name Get-ChildItem -Examples
# Results
<#
Get-ChildItem
Get-Childitem -System -File -Recurse
Get-ChildItem -Attributes !Directory,!Directory+Hidden
dir -att !d,!d+h
dir -ad
Get-ChildItem -File -Attributes !ReadOnly -path C:\ps-test
get-childitem . -include *.txt -recurse -force
get-childitem c:\windows\logs\* -include *.txt -exclude A*
get-childitem -name
#>
Get-help -Name Get-ChildItem -Full
Get-help -Name Get-ChildItem -Online
(Get-Command -NameR ename-Item).Parameters
(Get-Command -Name Rename-Item).Parameters.Keys|clip
# Results
<#
Path
LiteralPath
NewName
Force
PassThru
Credential
Verbose
Debug
ErrorAction
WarningAction
InformationAction
ErrorVariable
WarningVariable
InformationVariable
OutVariable
OutBuffer
PipelineVariable
WhatIf
Confirm
UseTransaction
#>
Get-help -Name Rename-Item -Examples
# Results
<#
Rename-Item -Path "c:\logfiles\daily_file.txt" -NewName "monday_file.txt"
Rename-Item -Path "project.txt" -NewName "d:\archive\old-project.txt"
Move-Item -Path "project.txt" -Destination "d:\archive\old-project.txt"
Rename-Item -Path "HKLM:\Software\MyCompany\Advertising" -NewName "Marketing"
Get-ChildItem *.txt | Rename-Item -NewName { $_.name -Replace '\.txt','.log' }
#>
Get-help -Name Rename-Item -Full
Get-help -Name Rename-Item -Online
Yet what you are doing in your code, is renaming the directory only, not the files in that directory or sub-directories. You have also not specified and start directory, so it will take action on whatever directory you are currently in vs the one you may want.
You need to loop all directors and loop all the files in those directories, to rename the files in that passed in the directory.
Update as per my '-WhatIf' comment
Just another way of doing what 'marzse' gave you, just with notification of what's being processed, and a check. Remove the -Whatif, if things look good, and run it again. Never ruin anyone's code if you are ae not absolutely sure what it is doing, or you are willing to accept the consequences of doing so.
Clear-Host
Get-ChildItem -Directory |
ForEach-Object {
"`n *** Working on resource named: $($PSItem.BaseName) *** `n"
$DirName = $($PSItem.BaseName)
Get-ChildItem -Path $DirName -File |
ForEach{
$PSItem.FullName |
Rename-Item -NewName "$($DirName)_$($PSItem)" -WhatIf
}
}
# Results test the rename process
<#
*** Working on resource named: AddressFiles ***
What if: Performing the operation "Rename File" on target "Item: D:\temp1\AddressFiles\(MSINFO32) command-line tool switches.pdf Destination: D:\temp1\AddressFiles\AddressFiles_(MSINFO32) command-line tool switches.pdf".
What if: Performing the operation "Rename File" on target "Item: D:\temp1\AddressFiles\File1.txt Destination: D:\temp1\AddressFiles\AddressFiles_File1.txt".
What if: Performing the operation "Rename File" on target "Item: D:\temp1\AddressFiles\File2.txt Destination: D:\temp1\AddressFiles\AddressFiles_File2.txt".
*** Working on resource named: ChildFolder ***
What if: Performing the operation "Rename File" on target "Item: D:\temp1\ChildFolder\5 Free Software You'll Wish You Knew Earlier! 2019 - YouTube.url Destination: D:\temp1\ChildFolder\ChildFolder_5 Free Software You'll Wish You Knew Earlier! 2019 - YouTube.url".
What if: Performing the operation "Rename File" on target "Item: D:\temp1\ChildFolder\awél.txt Destination: D:\temp1\ChildFolder\ChildFolder_awél.txt".
What if: Performing the operation "Rename File" on target "Item: D:\temp1\ChildFolder\hello.bat Destination: D:\temp1\ChildFolder\ChildFolder_hello.bat".
....
*** Working on resource named: dest ***
What if: Performing the operation "Rename File" on target "Item: D:\temp1\dest\mytest - 2019.txt Destination: D:\temp1\dest\dest_mytest - 2019.txt".
What if: Performing the operation "Rename File" on target "Item: D:\temp1\dest\mytest.txt Destination: D:\temp1\dest\dest_mytest.txt".
#>
Never rush into code or do all things at once. step in to in one step at a time to make sure you are getting what you'd expect at each step.
To get to the above, this is what I mean. Logical full step-thru, then once you understand you can optimize to what marsze shows.
Push-Location -Path 'D:\Temp1'
Get-Location
# Results
<#
Path
----
D:\temp1
#>
Get-ChildItem
# Results all file in the root
<#
Directory: D:\temp1
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 01-Nov-20 23:43 AddressFiles
d----- 01-Nov-20 23:43 BonoboGitServer
d----- 01-Nov-20 23:44 ChildFolder
...
#>
Get-ChildItem -Recurse
# Results all folder and file in root and sub-direcotries
<#
Directory: D:\temp1
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 01-Nov-20 23:43 AddressFiles
d----- 01-Nov-20 23:43 BonoboGitServer
d----- 01-Nov-20 23:44 ChildFolder
...
Directory: D:\temp1\AddressFiles
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 06-Aug-16 18:25 406508 (MSINFO32) command-line tool switches.pdf
-a---- 19-Mar-20 19:57 156 File1.txt
-a---- 19-Mar-20 19:57 150 File2.txt
...
#>
Get-ChildItem -Directory
# Results get only directory names
<#
Directory: D:\temp1
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 01-Nov-20 23:43 AddressFiles
d----- 01-Nov-20 23:43 BonoboGitServer
d----- 01-Nov-20 23:44 ChildFolder
...
#>
Get-ChildItem -Directory |
ForEach-Object {
Get-ChildItem -Path $PSItem.Name -Recurse |
Select-Object -Property Fullname
}
# Results use directory name to get all files in that directory tree
<#
FullName
--------
D:\temp1\AddressFiles\(MSINFO32) command-line tool switches.pdf
D:\temp1\AddressFiles\File1.txt
D:\temp1\AddressFiles\File2.txt
...
#>
Get-ChildItem -Directory |
ForEach-Object {
"`n *** Working on resource named: $($PSItem.BaseName) *** `n"
($DirName = $($PSItem.BaseName))
}
# Results
<#
*** Working on resource named: AddressFiles ***
AddressFiles
*** Working on resource named: BonoboGitServer ***
ChildFolder
*** Working on resource named: dest ***
...
#>
Get-ChildItem -Directory |
ForEach-Object {
"`n *** Working on resource named: $($PSItem.BaseName) *** `n"
$DirName = $($PSItem.BaseName)
Get-ChildItem -Path $DirName -File
}
# Results
<#
*** Working on resource named: AddressFiles ***
Directory: D:\temp1\AddressFiles
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 06-Aug-16 18:25 406508 (MSINFO32) command-line tool switches.pdf
-a---- 19-Mar-20 19:57 156 File1.txt
-a---- 19-Mar-20 19:57 150 File2.txt
*** Working on resource named: BonoboGitServer ***
*** Working on resource named: ChildFolder ***
Directory: D:\temp1\ChildFolder
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 29-Dec-19 21:50 69 5 Free Software You'll Wish You Knew Earlier! 2019 - YouTube.url
-a---- 10-Jan-20 17:59 0 awél.txt
-a---- 04-Jan-20 02:01 39 hello.bat
#>
Get-ChildItem -Directory |
ForEach-Object {
"`n *** Working on resource named: $($PSItem.BaseName) *** `n"
$DirName = $($PSItem.BaseName)
Get-ChildItem -Path $DirName -File |
ForEach{
$PSItem.FullName
}
}
# Results
<#
*** Working on resource named: AddressFiles ***
D:\temp1\AddressFiles\(MSINFO32) command-line tool switches.pdf
D:\temp1\AddressFiles\File1.txt
D:\temp1\AddressFiles\File2.txt
*** Working on resource named: BonoboGitServer ***
*** Working on resource named: ChildFolder ***
D:\temp1\ChildFolder\5 Free Software You'll Wish You Knew Earlier! 2019 - YouTube.url
D:\temp1\ChildFolder\awél.txt
D:\temp1\ChildFolder\hello.bat
...
#>
Upvotes: 1
Reputation: 17074
Use the -Recurse
switch to get items from subfolders too. Additionally you can also use the -File
switch to return files only:
(dir -File -Recurse) | Rename-Item -NewName {$_.Directory.Name + " - " + $_.Name}
Note: As @postanote pointed out, it's always recommendable to test destructive commands first using the -WhatIf switch.
Upvotes: 0