Gabe
Gabe

Reputation: 6097

Renaming a list of files and creating folder in Powershell

I'm in need a script, in PowerShell or batch script, that will do the following.

  1. Rename a file to append creation date minus 1 day to the filename.

    For example:

    foo.xlsx (created 7/27/2011)

    foo-2011-07-26.xlsx --note, it's yesterday's date.

    Date format isn't too important as long as it's there. There will be 10 files (all with the same creation date), so either I can copy and paste the same renaming line for the different files (just rename the filename) or just have the script affect all *.xlsx files in the existing folder.

  2. Create a new folder where those files are and name it 'fooFolder-2011-07-26' (yesterday's date).

  3. Move those renamed files to that folder.

I only have limited experience with PowerShell. It's on my todo list of languages to learn..

Upvotes: 1

Views: 2899

Answers (2)

Joel B Fant
Joel B Fant

Reputation: 24766

Here you go. It could be shortened up a lot using aliases and piping and whatnot, but since you're unfamiliar with Powershell still, I decided to write in a more procedural style for your reading:

function MoveFilesAndRenameWithDate([string]$folderPrefix, [string]$filePattern) {
  $files = Get-ChildItem .\* -include $filePattern
  ForEach ($file in $files) {
    $yesterDate = $file.CreationTime.AddDays(-1).ToString('yyyy-MM-dd')
    $newSubFolderName = '{0}-{1}' -f $folderPrefix,$yesterDate
    if (!(Test-Path $newSubFolderName)) {
      mkdir $newSubFolderName
    }
    $newFileName = '{0}-{1}{2}' -f $file.BaseName,$yesterDate,$file.Extension
    Move-Item $file (Join-Path $newSubFolderName $newFileName)
  }
}

You would paste the above into your Powershell session (place it in your profile). Then you call the function like this:

MoveFilesAndRenameWithDate 'fooFolder' '*.xslx'

I tend to use more aliases and piping than the above function. The first version I wrote was this, and then I separated parts of it to make it more comprehensible to a Powershell newcomer:

function MoveFilesAndRenameWithDate([string]$folderPrefix, [string]$filePattern) {
  gci .\* -include $filePattern |
    % { $date = $_.CreationTime.AddDays(-1).ToString('yyyy-MM-dd')
        mkdir "$folderPrefix-$date" 2>$null
        mv $_ (join-path $newSubFolderName ('{0}-{1}{2}' -f $_.BaseName,$date,$_.Extension))}
}

Edit: Modified both functions to create dated folder for the files that match that date. I considered making a temporary directory and grabbing a single date from the files moved to it, finally renaming the directory after the loop. However, if a day should be missed and files for 2 (or more) days get processed together, there would still be a folder for each day with these, which is more consistent.

Upvotes: 3

Andre Gross
Andre Gross

Reputation: 263

ok i´ve made it

 function NameOfFunction([string]$folderpath)
 {
    foreach ($filepath in [System.IO.Directory]::GetFiles($folderpath))
    {
        $file = New-Object System.IO.FileInfo($filepath);
        $date = $file.CreationTime.AddDays(-1).ToString('yyyy-MM-dd');
        if (![System.IO.Directory]::Exists("C:\\test\foo-$date"))
        {
            [System.IO.Directory]::CreateDirectory("$folderpath\foo-$date");
        }
        $filename = $file.Name.Remove($file.Name.LastIndexOf('.'));
        $fileext = $file.Name.SubString($file.Name.LastIndexOf('.'));
        $targetpath = "$folderpath\foo-$date" + '\' + $filename + '-' + $date + $fileext;
        [System.IO.File]::Move($filepath, $targetpath);
    }
 }

Explanation: First get all Files in the rootfolder. Foreach Folder we create a FileInfo-Object and get the CreationTime -1 Day. Then we check, if the Directory, which should be created, exists and create it if false. Then we get the filename and the extension. At the End we move the files to the new Directory, under the new Filename.

Hope that help you

Upvotes: 0

Related Questions