tar – extract discarding directory structure

35

10

unzip has a nifty option -j, whereby the directory structure of the archive is discarded, and all files are extracted into the same directory.

Is there a way of making tar work in the same way? Nothing in the man page seems to indicate so.

So, is there an alternative, preferably Free Software, tool that will do that?

Benji XVI

Posted 2009-11-17T20:58:33.020

Reputation: 453

Related: Extracting the Contents of tar archive to parent directory.

– G-Man Says 'Reinstate Monica' – 2015-03-14T00:59:36.497

Answers

82

GNU tar lives on featuritis, so naturally also has some options for that.
http://www.gnu.org/software/tar/manual/html_node/transform.html

If you just want to remove a few path segments, then --strip-components=n or --strip=n will often do:

 tar xvzf tgz --strip=1

But it's also possible to regex-rewrite the files to be extracted (flags are --transform or --xform and accept ereg with the /x modifer):

 tar xvzf tgz --xform='s#^[^/]+#.#x'
                 # or 's#^.+/##x' for discarding all paths

For listing a tar you need the additional --show-transformed option:

 tar tvzf tgz --show-transformed --strip=1 --xform='s/abc/xyz/x'

I believe the rewriting options also work for packing, not just for extracting. But pax has obviously a nicer syntax.

mario

Posted 2009-11-17T20:58:33.020

Reputation: 936

--strip not mentioned in the os x tar man page, but it works anyway, thanks! – slf – 2015-04-01T19:16:32.390

3Far better than the accepted answer. – Klaatu von Schlacker – 2016-02-10T08:28:02.750

is there any difference between --strip and --strip-components? – Joel B – 2019-02-20T09:37:23.487

@Joel It's the same. That's just a shortened version of the full parameter name. Technically you could even say --stri or --str, since that's still unambiguous. – mario – 2019-02-20T13:31:40.567

4Why not s#.*/##? – l0b0 – 2012-11-21T13:57:48.947

3--strip just made my day. Thanks! – SamStephens – 2012-12-02T01:33:48.443

13

You can do it fairly easily in two steps. Adapt as necessary:

$ mkdir /tmp/dirtree
$ tar xfz /path/to/archive -C /tmp/dirtree
$ find /tmp/dirtree -type f -exec mv -i {} . \;
$ rm -rf /tmp/dirtree

MikeyB

Posted 2009-11-17T20:58:33.020

Reputation: 1 232

1+1, tmpdir=$( mktemp -d ) is handy when creating temporary directories – sorki – 2013-05-22T08:12:16.587

this is how i'd do it (using find -exec mv -i instead of find | xargs).... simple steps i can repeat on any system without having to carry around a script to do it for me. – quack quixote – 2009-11-18T05:04:36.130

8

pax can do it:

pax -v -r -s '/.*\///p' < archive.tar

or

zcat archive.tar.gz | pax -v -r -s '/.*\///p'

You can check the name replacement operation first by omitting the -r option.

hfs

Posted 2009-11-17T20:58:33.020

Reputation: 338

1

A possible solution that doesn't require installing anything.

  1. use a tar tvf to grab all the files from the tarball
  2. Extract those files individually - have tar extract to stdout & redirect to $filename

    tar -tvf $1 | grep -v "^d" | \
                  awk '{for(i=6;i<NF+1;i++) {printf "%s ",$i};print ""}' |\
                  while read filename
                  do
                     tar -O -xf $1 "$filename" > `basename "$filename"`
                  done
    

save as extract.sh and run as extract.sh myfile.tar. It will also overwrite any duplicate filenames encountered in the directories pulled from the tarball.

DaveParillo

Posted 2009-11-17T20:58:33.020

Reputation: 13 402

Actually I just tested it on some a dir tree at home & It fails on files containing spaces. I'll see if I can't post an update. – DaveParillo – 2009-11-18T00:24:35.127

Fixed it, but it's not nearly as pretty as it was. – DaveParillo – 2009-11-18T00:39:06.977

-1

tar xf foo.tar.gz foo/path/to/file/bar.mp3 -O > bar.mp3

The -O option extracts a file to standard out, and > redirects that output into a file. So in my example I'm extracting foo.mp3 and redirecting it into bar.mp3. The file names are arbitrary.

Klaatu von Schlacker

Posted 2009-11-17T20:58:33.020

Reputation: 150