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