1

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..

1
  • Will the date be static or will it always be the day (minus 1) that the script is running? Commented Jul 27, 2011 at 19:41

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

4 Comments

The first parameter is not very nice. Because the name of the Subfolder is unknown because it´s defined by the CreationDate of the files (see his second point). It´s better to pass the directory where the files lay. But the rest of the script is nice.
Yeah, it would be better to only require him to pass the beginning part of the subfolder the files will be moved to and get the date from the files somehow, but I got the impression that it would only be one day at a time and the date would be known. If Gabe provides new information, I'll change it.
Thanks Joel. I plan to have this running daily as part of a scheduled job, so entering the date as part of the first parameter would not be ideal. The main folder and files will always be in one location (ie C:\reports) so I can pass that as a parameter or just hardcode it in the script.
@Gabe: I edited to include the need of generating part of the directory name. The function currently operates on the current directory (note the .\* after Get-ChildItem). You can hardcode that to C:\reports\*, or use cd C:\reports in your script before calling the function. Passing it as a parameter is an option, but I've found that you have to make sure it ends in \* for it to work properly in the way it is called above.
0

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

1 Comment

I'm not sure why you were downvoted? I'll give this is a try.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.