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