My company has millions of old reports in pdf form. They are Typically named in the format: 2018-09-18 - ReportName.pdf
The organization we need to submit these to is now requiring that we name the files in this format: Report Name - 2018-09.pdf
I need to move the first 7 characters of the file name to the end. I'm thinking there is probably an easy code to perform this task, but I cannot figure it out. Can anyone help me.
Thanks!
Caveat:
As jazzdelightsme points out, the desired renaming operation can result in name collisions, given that you're removing the day component from your dates; e.g.,
2018-09-18 - ReportName.pdfand2018-09-19 - ReportName.pdfwould result in the same filename,Report Name - 2018-09.pdf.Either way, I'm assuming that the renaming operation is performed on copies of the original files. Alternatively, you can create copies with new names elsewhere with
Copy-Itemwhile enumerating the originals, but the advantage ofRename-Itemis that it will report an error in case of a name collision.-WhatIfpreviews the renaming operation; remove it to perform actual renaming.Add
-Recurseto theGet-CildItemcall to process an entire directory subtree.The use of
-Filteris optional, but it speeds up processing.A script block (
{ ... }) is passed toRename-Item's-NewNameparameter, which enables dynamic renaming of each input file ($_) received fromGet-ChildItemusing a string-transformation (replacement) expression.The
-replaceoperator uses a regex (regular expression) as its first operand to perform string replacements based on patterns; here, the regex breaks down as follows:^(\d{4}-\d{2})matches something like2018-09at the start (^) of the name and - by virtue of being enclosed in(...)- captures that match in a so-called capture group, which can be referenced in the replacement string by its index, namely$1, because it is the first capture group.(.*?)captures the rest of the filename excluding the extension in capture group$2.?after.*makes the sub-expression non-greedy, meaning that it will give subsequent sub-expressions a chance to match too, as opposed to trying to match as many characters as possible (which is the default behavior, termed greedy).\.pdf$matches the the filename extension (.pdf) at the end ($) - note that case doesn't matter..is escaped as\., because it is meant to be matched literally here (without escaping,.matches any single character in a single-line string).$2 - $1.pdfis the replacement string, which arranges what the capture groups captured in the desired form.Note that any file whose name doesn't match the regex is quietly left alone, because the
-replaceoperator passes the input string through if there is no match, andRename-Itemdoes nothing if the new name is the same as the old one.