tar: transform

1 
1 6.7 Modifying File and Member Names
1 ===================================
1 
1 'Tar' archives contain detailed information about files stored in them
1 and full file names are part of that information.  When storing a file
1 to an archive, its file name is recorded in it, along with the actual
1 file contents.  When restoring from an archive, a file is created on
1 disk with exactly the same name as that stored in the archive.  In the
1 majority of cases this is the desired behavior of a file archiver.
1 However, there are some cases when it is not.
1 
1    First of all, it is often unsafe to extract archive members with
1 absolute file names or those that begin with a '../'.  GNU 'tar' takes
1 special precautions when extracting such names and provides a special
1 option for handling them, which is described in ⇒absolute.
1 
1    Secondly, you may wish to extract file names without some leading
1 directory components, or with otherwise modified names.  In other cases
1 it is desirable to store files under differing names in the archive.
1 
1    GNU 'tar' provides several options for these needs.
1 
1 '--strip-components=NUMBER'
1      Strip given NUMBER of leading components from file names before
1      extraction.
1 
1    For example, suppose you have archived whole '/usr' hierarchy to a
1 tar archive named 'usr.tar'.  Among other files, this archive contains
1 'usr/include/stdlib.h', which you wish to extract to the current working
1 directory.  To do so, you type:
1 
1      $ tar -xf usr.tar --strip=2 usr/include/stdlib.h
1 
1    The option '--strip=2' instructs 'tar' to strip the two leading
1 components ('usr/' and 'include/') off the file name.
1 
1    If you add the '--verbose' ('-v') option to the invocation above, you
1 will note that the verbose listing still contains the full file name,
1 with the two removed components still in place.  This can be
1 inconvenient, so 'tar' provides a special option for altering this
1 behavior:
1 
1 '--show-transformed-names'
1      Display file or member names with all requested transformations
1      applied.
1 
1 For example:
1 
1      $ tar -xf usr.tar -v --strip=2 usr/include/stdlib.h
1      usr/include/stdlib.h
1      $ tar -xf usr.tar -v --strip=2 --show-transformed usr/include/stdlib.h
1      stdlib.h
1 
1    Notice that in both cases the file 'stdlib.h' is extracted to the
1 current working directory, '--show-transformed-names' affects only the
1 way its name is displayed.
1 
1    This option is especially useful for verifying whether the invocation
1 will have the desired effect.  Thus, before running
1 
1      $ tar -x --strip=N
1 
1 it is often advisable to run
1 
1      $ tar -t -v --show-transformed --strip=N
1 
1 to make sure the command will produce the intended results.
1 
1    In case you need to apply more complex modifications to the file
1 name, GNU 'tar' provides a general-purpose transformation option:
1 
1 '--transform=EXPRESSION'
1 '--xform=EXPRESSION'
1      Modify file names using supplied EXPRESSION.
1 
1 The EXPRESSION is a 'sed'-like replace expression of the form:
1 
1      s/REGEXP/REPLACE/[FLAGS]
1 
1 where REGEXP is a "regular expression", REPLACE is a replacement for
1 each file name part that matches REGEXP.  Both REGEXP and REPLACE are
1 described in detail in ⇒The "s" Command (sed)The "s" Command.
1 
1    Any delimiter can be used in lieu of '/', the only requirement being
1 that it be used consistently throughout the expression.  For example,
1 the following two expressions are equivalent:
1 
1      s/one/two/
1      s,one,two,
1 
1    Changing delimiters is often useful when the REGEX contains slashes.
1 For example, it is more convenient to write 's,/,-,' than 's/\//-/'.
1 
1    As in 'sed', you can give several replace expressions, separated by a
1 semicolon.
1 
1    Supported FLAGS are:
1 
1 'g'
1      Apply the replacement to _all_ matches to the REGEXP, not just the
1      first.
1 
1 'i'
1      Use case-insensitive matching.
1 
1 'x'
11      REGEXP is an "extended regular expression" (⇒Extended regular
      expressions (sed)Extended regexps.).
1 
1 'NUMBER'
1      Only replace the NUMBERth match of the REGEXP.
1 
1      Note: the POSIX standard does not specify what should happen when
1      you mix the 'g' and NUMBER modifiers.  GNU 'tar' follows the GNU
1      'sed' implementation in this regard, so the interaction is defined
1      to be: ignore matches before the NUMBERth, and then match and
1      replace all matches from the NUMBERth on.
1 
1    In addition, several "transformation scope" flags are supported, that
1 control to what files transformations apply.  These are:
1 
1 'r'
1      Apply transformation to regular archive members.
1 
1 'R'
1      Do not apply transformation to regular archive members.
1 
1 's'
1      Apply transformation to symbolic link targets.
1 
1 'S'
1      Do not apply transformation to symbolic link targets.
1 
1 'h'
1      Apply transformation to hard link targets.
1 
1 'H'
1      Do not apply transformation to hard link targets.
1 
1    Default is 'rsh', which means to apply transformations to both
1 archive members and targets of symbolic and hard links.
1 
1    Default scope flags can also be changed using 'flags=' statement in
1 the transform expression.  The flags set this way remain in force until
1 next 'flags=' statement or end of expression, whichever occurs first.
1 For example:
1 
1        --transform 'flags=S;s|^|/usr/local/|'
1 
1    Here are several examples of '--transform' usage:
1 
1   1. Extract 'usr/' hierarchy into 'usr/local/':
1 
1           $ tar --transform='s,usr/,usr/local/,' -x -f arch.tar
1 
1   2. Strip two leading directory components (equivalent to
1      '--strip-components=2'):
1 
1           $ tar --transform='s,/*[^/]*/[^/]*/,,' -x -f arch.tar
1 
1   3. Convert each file name to lower case:
1 
1           $ tar --transform 's/.*/\L&/' -x -f arch.tar
1 
1   4. Prepend '/prefix/' to each file name:
1 
1           $ tar --transform 's,^,/prefix/,' -x -f arch.tar
1 
1   5. Archive the '/lib' directory, prepending '/usr/local' to each
1      archive member:
1 
1           $ tar --transform 's,^,/usr/local/,S' -c -f arch.tar /lib
1 
1    Notice the use of flags in the last example.  The '/lib' directory
1 often contains many symbolic links to files within it.  It may look, for
1 example, like this:
1 
1      $ ls -l
1      drwxr-xr-x root/root       0 2008-07-08 16:20 /lib/
1      -rwxr-xr-x root/root 1250840 2008-05-25 07:44 /lib/libc-2.3.2.so
1      lrwxrwxrwx root/root       0 2008-06-24 17:12 /lib/libc.so.6 -> libc-2.3.2.so
1      ...
1 
1    Using the expression 's,^,/usr/local/,' would mean adding
1 '/usr/local' to both regular archive members and to link targets.  In
1 this case, '/lib/libc.so.6' would become:
1 
1        /usr/local/lib/libc.so.6 -> /usr/local/libc-2.3.2.so
1 
1    This is definitely not desired.  To avoid this, the 'S' flag is used,
1 which excludes symbolic link targets from filename transformations.  The
1 result is:
1 
1      $ tar --transform 's,^,/usr/local/,S' -c -v -f arch.tar \
1             --show-transformed /lib
1      drwxr-xr-x root/root       0 2008-07-08 16:20 /usr/local/lib/
1      -rwxr-xr-x root/root 1250840 2008-05-25 07:44 /usr/local/lib/libc-2.3.2.so
1      lrwxrwxrwx root/root       0 2008-06-24 17:12 /usr/local/lib/libc.so.6 \
1       -> libc-2.3.2.so
1 
1    Unlike '--strip-components', '--transform' can be used in any GNU
1 'tar' operation mode.  For example, the following command adds files to
1 the archive while replacing the leading 'usr/' component with 'var/':
1 
1      $ tar -cf arch.tar --transform='s,^usr/,var/,' /
1 
1    To test '--transform' effect we suggest using
1 '--show-transformed-names' option:
1 
1      $ tar -cf arch.tar --transform='s,^usr/,var/,' \
1             --verbose --show-transformed-names /
1 
1    If both '--strip-components' and '--transform' are used together,
1 then '--transform' is applied first, and the required number of
1 components is then stripped from its result.
1 
1    You can use as many '--transform' options in a single command line as
1 you want.  The specified expressions will then be applied in order of
1 their appearance.  For example, the following two invocations are
1 equivalent:
1 
1      $ tar -cf arch.tar --transform='s,/usr/var,/var/' \
1                              --transform='s,/usr/local,/usr/,'
1      $ tar -cf arch.tar \
1                     --transform='s,/usr/var,/var/;s,/usr/local,/usr/,'
1