Cycle through sub-folders to rename files in Power

2019-09-15 15:48发布

问题:

I have a file directory that contains many folders within it. Inside each of these sub-folders, I have a variety of files. I would like to go through each file, rename some of the items, and add extensions to some of them. I am using Powershell to do this.

I have file names with "." that all need to be replaced with "_" for example, "wrfprs_d02.03" should be "wrfprs_d02_03". I was able to successfully do that in one folder with the following code:

dir | rename-item -NewName {$_.name -replace "wrfprs_d02.","wrfprs_d02_"}

After, I make those replacements, I want to add .grb extensions on to some of the files, which all happen to start with "w", and I was able to do that within one folder with:

Get-ChildItem | Where-Object {$_.Name -match "^[w]"} | ren -new {$_.name + ".grb"}

When I step back from one folder and try to do it iteratively within many folders, my code doesn't work. I am in a directory called "Z:\Windows.Documents\My Documents\Test_data\extracted" which contains all my sub-folders that I want to iterate over. I am using the following code:

$fileDirectory = "Z:\Windows.Documents\My Documents\Test_data\extracted"
foreach($file in Get-ChildItem $fileDirectory)
{
dir | rename-item -NewName {$_.name -replace "wrfprs_d02.","wrfprs_d02_"}
Get-ChildItem | Where-Object {$_.Name -match "^[w]"} | ren -new {$_.name + ".grb"}
}

Any ideas on what my problem is?

回答1:

because you $_ is replaced into loop when you use pipe. I propose you a new code:

$fileDirectory = "Z:\Windows.Documents\My Documents\Test_data\extracted"

Get-ChildItem $fileDirectory -recurse -file -filter "*.*" |
%{

#replace . by _
$NewName=$_.Name.Replace(".", "_")

#add extension grb if name start by w
if ($NewName -like "w*") {$NewName="$NewName.grb"}

#Add path file
$NewName=Join-Path -Path $_.directory -ChildPath $NewName
#$NewName

#rename
Rename-Item $_.FullName $NewName

}


回答2:

Not sure what error you were getting, but using rename-item can be finicky. Or at least so in my experience.

I used the follow without issue. My files names were different so I replaced all periods with underscores. If the file starts with "W" then it changed the extension for that file.

$FilePath = Get-ChildItem "Z:\Windows.Documents\My Documents\Test_data\extracted" -Recurse -File
foreach ($file in $FilePath)
{
    $newName = $file.Basename.replace(".","_") 
    $New = $newName + $file.Extension

    if($file.Name -match "^[w]")
    {
          Rename-Item $file.FullName -NewName "$($New).grb" 
    }
    else
    {
         Rename-Item $file.FullName -NewName $New
    }
 }

Hope that helps.