[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Pitfalls in rename, was Re: cp output format



Quoting Renaud OLGIATI (renaud@olgiati-in-paraguay.org):
> On Thu, 16 Jul 2015 11:51:26 -0500
> David Wright <deblis@lionunicorn.co.uk> wrote:
> 
> > > > How do I get rid of the "~" so that the backups are file.1, file.2,
> > > > etc.?   
> 
> > > How about using the GNU rename in the dir holding your backup files:
> > > $ rename "~" "" *~*  
> 
> > Would that not be something more like
> > rename 's/\.~([0-9]+)~$/.$1/' *[0-9]~
> 
> Which is why I stick to the GNU version of rename, and shun the perl version; much simpler syntax.

Thanks for that comment. Though I migrated from Perl to Python a
couple of decades ago, I always install the proper Perl package,
so I get rename→prename rather than rename→rename.ul . Yes,
rename.ul has a simpler syntax, but it's far more dangerous.

Whereas I wrote *[0-9]~ for the shell pattern where * would have
sufficed (because Perl's pattern is so specific), _your_ shell pattern
needs to be even more specific than *[0-9]~ (needing to match the
.~ and therefore multiple digits too). As it is, you will clobber the
first ~ irrespective of its position.

You'll then need a second pass because rename.ul only replaces one
occurrence of ~.

And woe betide any files like foo.2 already present: rename.ul will
silently overwrite it with any of foo.2~ foo.~2 or even ~foo.2
that get renamed.

In fact while testing this, I accidently stumbled on the bizarre
case where the set of files:
   0 Jan  1  2011 ~foo.2
 220 Jan  1  2010 foo.2
   0 Jan  1  2012 foo.~2
 850 Jan  1  2013 foo.~2~
   0 Jan  1  2014 foo.2~
is reduced to
 850 Jan  1  2013 foo.2
by a single application of rename.ul "~" "" *~* and the "correct" one wins!

Anyway, checkout the man page and heed the warning. Meanwhile I shall
cultivate the habit of typing "prename", like with rm -i and mv -i.
And I've edited the single occurrence of a bare rename in my .bashrc,
though I don't think any filenames would accidentally match
 "tr/A-Z/a-z/;s/[),(\`\'’\"]/ /g;s/  / /g;s/ /-/g;s/--/-/g;s/^-//g;s/-$//g"
except as a Perl pattern.

Cheers,
David.


Reply to: