Newer
Older
tren / tren.rst
@tundra tundra on 19 Jan 2010 23 KB Further minor edits.
NAME
----

**tren** - Advanced File Renaming

SYNOPSIS
--------

::

    tren.py [-cbefghqtvx] [-l string] [-r old=new]... file|dir file|dir ...


DESCRIPTION
-----------

.. WARNING:: **tren** is a powerful file and directory renaming tool.
             Be **sure** you know what you're about to do.  If you're
             not, run the program in test mode (invoke with the ``-t``
             option) to see what could happen.  You have been warned!

**tren** is a general purpose file and directory renaming tool. Unlike
commands like ``mv``, **tren** is particularly well suited for
renaming *batches* of files and/or directories with a single command
line invocation.  **tren** eliminates the tedium of having to script
simpler tools to provide higher-level renaming capabilities.

**tren** will not allow you to rename a file or directory if one with
the new name already exists. Such attempts will cause no change to the
file or directory being processed and a warning message will be
displayed.  This is intentional to force you to manually rename or
remove the file or directory that would have been clobbered by a
rename.  You can override this default and *force* a renaming and thus
the removal of such existing files or directories (``-f`` option).

**tren** supports a variety of renaming mechanisms.  The one thing
they have in common is that you must specify an *old string* which
will be replaced by a *new string* when the file or directory is
renamed.  Each of these can take on one of several forms:

  ----------                    ----------
  Old String                    New String
  ----------                    ----------

  Literal Text                  Literal Text
  Regular Expression            Literal Text With Templates
  Literal Text With Templates

The sections below describe each of these mechanisms.


Literal String Substitution
---------------------------

Literal String Substitution is just that - it replaces one literal
string with another to rename the target file or directory.  This is
handy when you have files and directories that have a common set of
characters in them you'd like to change.  For instance::

  tren.py -r .Jpeg=.jpg *.Jpeg

would rename all files (or directories) whose names contained the
string ``.Jpeg`` and replace it with ``.jpg``.  It's important to
realize that such a substitution takes place *anywhere* in the file
name, not just at the end or "extension" (as it is called in Windows).
You can limit the replacement to just the "name" (``-b``) or
"extension" (``-e``) portions of the filename.

You may specify multiple replacement operations (``-r``) on the **tren** 
command line::

  tren.py -r .Jpeg=.jpg -r old=ReallyOld *

This would rename all the files in the current directory, replacing
``.Jpeg`` with ``.jpg`` and ``old`` with ``ReallyOld`` anywhere these
strings appeared in any of the file or directory names.

By default, only the first instance of the string is replaced in the
name, but you can use the ``-g`` option to replace *all* instances of
the old string with the new one.

If you need to include the equals sign as part of the old string or
the new string literal text, you have to escape it (``\=``)::

  tren.py -r name\=bob=name\=sally name=bob.dbms

This renames the file ``name=bob.dbms`` to ``name=sally.dbms``.


Using Regular Expressions
-------------------------

Ordinarily **tren** treats both the old string you specify with the
``-r`` option *literally*.  However, it is sometimes handy to be able
to write a regular expression to specify what you want replaced.  If
you specify the ``-x`` option, **tren** will treat your old string as
a Python style regex, compile it (or try to anyway!) and use it to
select which strings to replace.  This makes it much easier to rename
files that have repeated characters or patterns, and groups of files
that have similar, but not idential strings in their names you'd like
to replace.

Say you have a set of files that are similar, but not idential in
name, and you want to rename them all::

  sbbs-1.txt
  sbbbs-2.txt
  sbbbbbbbbs-3.txt

Suppose you want to rename them, replacing two or more instances of
``b`` with ``X``. It is tedious to have to write a separate literal
``-r old:new`` string substitution for each instance above.  This is
where regular expressions can come in handy.  When you invoke the
``-x`` option, **tren** understands this to mean that the ``old``
portion of the replacement option is to be treated as a *Python style
regular expression*.  That way, a single string can be used to match
many cases::
 
  tren.py -x -r bb+:X *.txt

This renames the files to::

  sXs-1.txt
  sXs-2.txt
  sXs-3.txt

Keep in mind that a literal string is a subset of a regular
expression.  This effectively means that with ``-x`` processing
enabled you can include *both* regular expressions and literal text in
your "old string" specification.  The only requirement is that the
string taken as a whole be a valid Python regular expression.  If it
is not, **tren** will display an error message to that effect.

Because Python regular expressions can make use of the ``=`` symbol,
you need a way to distinguish between an ``=`` used in a regular
exression and the same symbol used to separate the old and new
operands for the ``-r`` option.  Where this symbol needs to appear in
a regular expression, it has to be escaped like this: ``\=``.


An Overview Templates
---------------------

**tren** implements the notion of *Renaming Templates*.  These can
appear in either the old- or the new string components of a ``-r``
renaming argument.

It is sometimes useful to be able to take a group of files or
directories whose names have nothing in common and impose a common
naming scheme on them.  For example, suppose you and your friends pool
your vacation photos but each of your cameras uses a slightly
different naming scheme.  You might want to just reorder them by the
date and time each picture was taken, for example.  That way you end
up with one coherent set of named and numbered files.  You might have
something like this::

  DSC002.jpg      (Bob's camera,  taken 1-5-2010 at noon)
  dc0234.Jpg      (Mary's camera, taken 1-5-2010 at 8am)
  032344.jpeg     (Sid's camera,  taken 1-3-2010 at 4pm)

It would be nice to get these in order somehow.

*Renaming Templates* provide this ability.  Given a list of files,
you apply a "template" or pattern to be used when renaming them. This
template is nothing more than a string containing so-called *Renaming
Tokens* built into **tren**, and optionally, literal text, and even
regular expressions (old string only).

There's a whole section later in this document on template
construction and the use of renaming tokens, but here's a simple
example to illustrate the general idea using the files above::

  tren.py -r =/D/-MyVacation-/+T0001/.jpeg *.jp*

This would rename all the files in the current directory ending with
``.jp*``.  The ``/D/`` would be replaced with the *date* the picture
was taken. The ``/+T0001/`` refers to a *starting sequence number* to
uniquely identify pictures taken on the same date.  The other strings
in the template, ``-MyVacation-`` and ``.jpeg``, are inserted
*literally* in the final file names.  After we ran this command, the
files above would end up with these names::

  20100103-MyVacation-0001.jpeg       (Sid's)
  20100105-MyVacation-0001.jpeg       (Mary's)
  20100105-MyVacation-0002.jpeg       (Bob's)

Notice that the files taken on the same date have been sequenced by
the time-of-day they were taken because we included the ``/+T0001/``
renaming token in our pattern.  The ``+`` here means to construct
the sequence in *ascending* order.  A ``-`` would specify
*descending* order.  

Notice that there is *no old string* in our example above.
That is, there is nothing to the left of the ``=`` symbol
in the ``-r`` option.  This effectively means "match anything"
in the existing file or directory name.  If you were using
regular expressions (``-x``) you could do the same thing
with::

  -r *=/D/-MyVacation-/+T001/.jpeg *.jp*

Ordinarily the template text replaces the *entire* existing filename
when you do this.  You can limit the replacement to either the "name"
(``-b``) or "extension" (``-e``) portions of the filename.

Of course, you don't *have* to replace the entire filename when
using templates.  It's perfectly legitimate to replace only
a portion of the existing name::

   tren.py -r file=/D/-file  file-1 file.2

This would rename our files to: ``20100101-file-1 and 20100101-file.2``

You can even use templates in your *old string* specification.
For instance, suppose you manage a number of different systems
that set their system name in an environment variable called SYSNAME.
You might then do something like this::

  tren.py -x -r /$SYSNAME/*.bku=/$SYSNAME/*.bku.old

If your system name were "matrix", then the command above would only
rename files in the form ``matrix<anytext>.bku``.  If your system name
were "modar", then the command above would only rename files in the
form ``modar<anytext>.bku``.

There are a couple of things to keep in mind when doing things like
this:

  1) The ``/$SYSNAME/`` in the old string is used to *find the
     text to rename*, whereas the same renaming token in the
     new string means *insert the contents of that environment
     variable here*.

  2) Renaming tokens are always evaluated *before* any regular
     expression processing takes place.  It's up to you to
     make sure that when you combine the two (as we have in
     the example above), *that the final result is still a 
     valid Python regular expression*.  This may involve
     explicit quoting of the renaming tokens used in the old
     string specification. 


There are many other renaming tokens and ways to construct
all manner of clever templates.  These are discussed below in the
section entitled `TEMPLATE CONSTRUCTION`_.


OPTIONS
-------

  -b   Only perform renaming within "name" portion of file
       or directory name.

        (*Default*: Substitute within the entire file or directory name)

       Many applications use the suffix of a filename to indicate the
       contents or type of file.  By default, **tren** does renaming
       in the entire filename *including* the extension.  For example
       doing this::

         tren.py -r eg=ug   peg.jpeg

       Renames the file to ``pug.jpug`` .. probably not what you want.

       The ``-b`` option tells **tren** to only perform string renaming
       in the actual "name portion" of the filename thereby
       cirumventing problems like this::

         tren.py -b -r eg=ug   peg.jpeg   # Renames file to pug.jpeg
     
  -c   Collapse case when doing string substitution.

        (*Default*: Search for string to replace is case sensitive.)

       When looking for a match on the old string to replace,
       **tren** will ignore the case of the characters found
       in the filename.  For example::

         tren.py -c -r Old:NEW Cold.txt fOlD.txt

       This renames both files to ``CNEW.txt`` and ``fNEW.txt``
       respectively.  Notice that the new (replacement) string's case
       is preserved.

  -e   Only perform renaming within "extension" portion of
       or directory name.

        (*Default*: Substitute within the entire file or directory name)

       This option is the inverse of ``-b``.  It instructs **tren**
       to do the requested renaming *only* in the filename
       "extension" not on the file name portion.  For example::

          tren.py -e -r pe=p   peg.jpeg   # Renames file to peg.jpg

  -f   Force renaming even if target file or directory name already
       exists.

        (*Default*: Skip renaming if a file or directory already
        exists by the same name as the target.)

  -g   Replace all instances (greedy replace) of the old string 
       with the new.

        (*Default*: Only the first matching string is replaced.)

       Ordinarily, **tren** only replaces the single *leftmost*
       instance of a string in the entire filename (default), the name
       portion (``-b``) or the extension (``-e``).  If you want
       *all* instances of a particular string replaced, use this
       option to enable "greedy" replacement::

         tren.py -g -r p:P pop.txp    # Renames file to: PoP.txP

  -h   Print help information.


  -l string   File "extension" delimiter string.

               (*Default*: ".")

              **tren** has to know what separates the "name" from the
              "extension" in a filename.  By default, it uses the
              rightmost ``.`` character.  You can change it with this
              option to "divide" the filename into name and extension
              for renaming purposes, using any string you like.  This
              is particularly helpful with ``-b`` and ``-e`` options::

                tren.py -b -l .long.txt -r long:short long.long.txt.long.txt.foo

              This would rename the file to::

                short.short.txt.long.txt.foo

              Notice that **tren** looks for the *rightmost* instance
              of the separator to split the whole filename into name
              and extension components.  Notice also that when you do
              this, no renaming of characters *within* the separator
              takes place.

  -q   Quiet mode, do not show progress.

        (*Default*: Display progress)

       Ordinarily, **tren** displays what it is doing as it
       processes each file.  If you prefer to not see this
       "noisy" output, use the ``-q`` option.  Note that this
       does not suppress warning and error messages.

       This option is ignored when running in test mode (``-t``).


  -r <old=new>   Replace "oldstring" with "newstring" in file names.

                 Use this option to specify which strings you
                 want to replace in each file name. These strings
                 are treated literally unless you also invoke
                 the ``-x`` option.

                 You can have multiple instances of this option on
                 your **tren** command line::

                   tren.py -e old:new -e txt:doc old-old.txt

                 This renames the file to::

                   new-old.doc
               
                 By default, **tren** only replaces the first
                 (leftmost) instance of the old string with the new.
                
                 This option's behavior is modified by the ``-b``,
                 ``-c``, ``-e``, ``g``, ``l``, and ``x`` options.

                 If you need to use the ``=`` symbol *within* either
                 the old or new string, simply escape it: ``\=``


  -t   Test mode, don't rename, just show what the program *would* do
       (ignores -q).

       **tren** is very powerful and capable of doing nasty things to
       your files (like making a file disappear when another one is
       renamed over it).   For this reason, it is helpful to test
       your **tren** commands before actually using them.  With this
       option enabled, **tren** will print out diagnostic information
       about what your command *would* do, *without actually doing it*.


  -v   Print detailed program version information and exit.

  -x   Treat the old string in a ``-r`` replacement as a Python
       style regular expression for matching purposes.

        (*Default*: Treat the old string as literal text)



TEMPLATE CONSTRUCTION
---------------------

Template based renaming is used when you want to impose a naming
"pattern" on a group of files or directories.  This is most useful
when the existing filenames have little or nothing in common.  In such
situations, there's often no direct way to use string substitutions to
order the names in some coherent way.

A "template" is built from literal text and *renaming tokens*.  These
tokens are delimited by the ``/`` character.  **tren** replaces these
tokens with corresponding information (see descriptions below) to
produce a final "template text".  The template text is the actual
string used to either replace the existing file or directory name (or
just the "name" or "extension" portions, depending on which options
you've selected) or to be appended or prepended to the name.

Currently, **tren** defines a number of renaming tokens.

File Attribute Renaming Tokens
------------------------------

These tokens are derived from information about the file or
directory being renamed.



``/D/       File or directory creation date``

              This token is replaced with the date of creation
              of the file or directory being renamed.  It is
              in ``YYYMMDD`` format.

``/E/       Original File Extension``

              This token is replaced the "extension" portion of the file
              or directory before renaming.  This does not include the
              extension separator string.

``/F/       Original File Name``

              This token is replaced the "name" portion of the file or
              directory before renaming.

.. NOTE:: Notice that there is no token for the *whole* filename
          because you can always synthesize it with ``/F/./E/``


``/G/       File or directory primary group name``

              This token is replaced with the name of the
              primary group to which the file belongs.

``/I/       File or directory creation date``

              This token is replaced with the date of creation of the
              file or directory being renamed.  It is similar to ``/D/``
              except it is in ISO format, ``YYYY-MM-YY``.

``/S/       File or directory size``

              This token is replaced with a numeric string
              that indicates the size of the file or directory
              in bytes.

``/T/       File or directory creation time``

              This token is replaced with the time of creation
              of the file or directory being renamed.  It is
              in ``HH:MM:SS`` format.

``/U/       File or directory owner name``

              This token is replaced with the name of the
              file or direcotry's owner.


Sequence Renaming Tokens
------------------------

Sometimes it's useful to rename files or directories based on some
*property they possess* like the date or time of creation, the size of
the file, who owns it, and so on.  That's the idea behind the ``/D/``,
``/T/``, and ``/S/`` renaming tokens described in the previous section.

An extension of this idea is to *order all the files being renamed*
based on one of these parameters.  For instance, instead of actually
embedding the date and time of creation in a file or directory name,
you might want to order the files from oldest to newest with a naming
convention like::

  file-1.txt
  file-2.txt
  file-3.txt

This guarantees uniqueness in the final name and also sees to it that
a sorted directory listing will show you the files or directories in
the order you care about.

This is the purpose of *sequence renaming tokens*.  They give you
various ways to create sequences that can be embedded in the final
file or directory name.

General Format Of Sequence Renaming Tokens
------------------------------------------

Sequence renaming tokens consist of three descriptive components and
have the following general format::

    /<ordering flag><type><counting pattern>/
  
      where,
             ordering flag: 
  
                   +  ascending
                   -  descending
  
             type:
  
                   D  sequence on file creation date & time
                   R  sequence on the command line file order
                   S  sequence on file size
                   T  sequence on file creation time within a given day


Count Pattern Format
--------------------

The counting pattern is used to specify two things: The width of the
sequence string, and the starting value for the sequence.  Examples::

  0001    ->   0001, 0002, 0003, ...
  0000    ->   0000, 0001, 0002, ...
  03      ->   03, 04, 05, ...

You do not have to use a ``0`` to indicate the sequence width.  You
can use *any* padding characters you like.  **tren** only cares about
the width of the field and will "consume" your padding characters as
the count increases.::

  xxx3    ->   xxx3, xxx4, xxx5, ... 9999, xxx3, xxx4, ...
   -+8    ->   -+8, -+9, -10, -11, ... 999, -+8, -+9, ...

You are not restricted to numbers in a counting pattern.  Letters may
also be used.  **tren** will preserve the case you specify in the
template when creating sequences like this::

  000a    ->   000a, 000b, 000c, ... zzzz, 000a, ...
  ---Y    ->   ---Y, ---Z, --AA, ... ZZZZ, ---Y, ---Z, ...

Notice that when a sequence "rolls over", the next value is the
*initial sequence value you specified*.



System Related Renaming Tokens
------------------------------

These tokens are derived from the underlying operating system
and runtime environment.

``/$ENV/     Environment variable``

               This token is replaced with the value of
               the environment variable ``$ENV``.  If
               that variable does not exist, the token
               is replaced with an empty string.


``/\cmd\`/`` Arbitrary command execution``

               This token is replaced with the text
               returned by executing the ``cmd`` command.


EXAMPLES
--------

Here are some common examples of **tren** in action - the resulting
file name(s) shown to the right as a comment.  Study each example
carefully.  Small subtleties are introduced in various
adjacent examples to illustrate diffent features of **tren**:


  Simple rename::

    tren.py -r old=New  fold.txt log.old     # fNew.txt log.New

  Change file "name"::

    tren.py -b -r old=New  fold.txt log.old  # fNew.txt log.old

  Change file "extension"::

    tren.py -e -r old=New  fold.txt log.old  # fold.txt log.New

  Rename all instances of a given string::

    tren.py -g -r bin=Bin binary_bin.binbin  # Binary_Bin.BinBin

  Rename, ignoring case::

    tren.py -c -r bin=BIN Binary_bIN.txt     # BINary_bIN.txt

  Rename multiple strings at once::

    tren.py -r log:txt -r New:old New.log    # old.txt

  Rename using regular expressions::

    tren.py -x -r a+=a  Saaaaaaaally.doc     # Sally.doc

  Rename a file containing the ``=`` symbol::

    tren.py -r a\=b=c\=d  a=b.txt            # c=d.txt

  Use template::

    tren.py -T /I/ file.1                    # 2010-01-12

  Use template to change file "name"::

    tren.py -b -T /I/ file.1 file.2          # 2010-01-12.1 2010-01-12.2

  Use template to change file "extension"::

    tren.py -e -T /D/ file.1                 # file.20100112

  Get help::

    tren.py -h

  Print out detailed version information::

    tren.py -v


OTHER
-----

You must have a reasonably current version of Python installed.


BUGS AND MISFEATURES
--------------------

None known as of this release.


COPYRIGHT AND LICENSING
-----------------------

**tren** is Copyright (c) 2010 TundraWare Inc.

For terms of use, see the ``tren-license.txt`` file in the
program distribution.  If you install **tren** on a FreeBSD
system using the 'ports' mechanism, you will also find this file in
``/usr/local/share/doc/tren``.


AUTHOR
------

::

   Tim Daneliuk
   tren@tundraware.com



DOCUMENT REVISION INFORMATION
-----------------------------

::

  $Id: tren.rst,v 1.124 2010/01/19 20:52:14 tundra Exp $

You can find the latest version of this program at:

  http://www.tundraware.com/Software/tren