I have a tarfile which has the following structure:

- dir1
 -- file
- dir2
- dir3

If I try running tar -xf tarfile.tar.gz dir1/file, dir1 containing the file will be created. I would like instead to just get the file without the directory in between. I could move the file and delete the directory, but I was wondering if the tar command offers support for doing that directly.

I am using Alpine Linux.

  • 2
    Does your system's version of tar support the --strip-components option? Sep 26, 2016 at 17:20
  • It does on Ubuntu. However, I just realized that I won't be using ubuntu for this command, but Alpine instead. I need to recheck if there's support for it. Sep 26, 2016 at 17:22
  • @steeldriver It is supported (I just need to upgrade) Sep 26, 2016 at 17:26

3 Answers 3


POSIXly (except for the gunzip part that is not a POSIX command):

gunzip < file.tar.gz | pax -rs'|.*/||' dir1/file1

With bsdtar:

tar -s'|.*/||' -xf file.tar.gz dir1/file1

With GNU tar:

tar --transform='s|.*/||' -xf file.tar.gz dir1/file1

With star:

star -s '|*/||' -x -f file.tar.gz dir1/file1

Note that for some of those, if the file is a a symlink, the substitution will also affect the target of the symlink.

  • tar --transform works on Alpine (after upgrading). I ended up using the suggestion in the comments, but I will accept your answer since it also works. Sep 26, 2016 at 20:58

You could extract to stdout (-O) and pipe it to the wanted filename.

  • 1
    Though that would only work for regular files and you'd loose the file metadata (ownership, time, permission...). Sep 26, 2016 at 20:42

Here is my solution in Ruby. I make no attempt to handle sym-links properly, but that could be added of course.

outfiles = `tar zxvf #{ARGV[0]}`
root_dirs = {}
outfiles.each_line do |l|
  s = l.split('/')
  root_dirs[s[0]] = 1
  `mv #{l.chomp} ./#{s[-1]}`
root_dirs.each_key {|rd| `rm -rf #{rd}`}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .