Say I have file named
ugly_name.tar, which when extracted, becomes
ugly_name directory. What command can I use such that the resulting directory name is
This should work:
mkdir pretty_name && tar xf ugly_name.tar -C pretty_name --strip-components 1
-C changes to the specified directory before unpacking (or packing).
--strip-components removes the specified number of directories from the filenames stored in the archive.
Note that this is not really portable. GNU tar and at least some of the BSD tars have the
--strip-components option, but doesn't seem to exist on other unix-like platforms.
The dumb way of doing this would work pretty much everywhere though.
tar xf ugly_name.tar && mv ugly_name pretty_name
tar xf foo.tar --transform 's!^ugly_name\($\|/\)!pretty_name\1!'
ugly_name is the toplevel component of all the file names in the archive, you don't need to bother with precise matching:
tar xf foo.tar --transform 's/ugly_name/pretty_name/'
If you don't know the name of the toplevel directory, you can still use this method, though you might prefer
tar xf foo.tar --transform 's!^[^/]\+\($\|/\)!pretty_name\1!'
pax, the POSIX archive utility, use the
-s option, which takes a sed-like replacement expression as an argument.
pax -rf foo.tar -s '!^ugly_name\($\|/\)!pretty_name\1!' pax -rf foo.tar -s '/ugly_name/pretty_name/' pax -rf foo.tar -s '!^[^/]\+\($\|/\)!pretty_name\1!'
From askUbuntu, this answer worked for me:
tar zxvf ugly_name.tgz --one-top-level=pretty_name
Tells tar to create a new directory beneath the extraction directory (or the one passed to `-C') and use it to guard against tarbombs. In the absence of dir argument, the name of the new directory will be equal to the base name of the archive (file name minus the archive suffix, if recognized). Any member names that do not begin with that directory name (after transformations from `--transform' and `--strip-components') will be prefixed with it. Recognized file name suffixes are `.tar', and any compression suffixes recognizable by See -auto-compress.
As pointed out in the comments, this method does not work for archives that are properly formed, however as another answer shows, you should add
--strip-components 1 for this to really work. I have tested with this new option and it works both for archives with a top-level name and ones without.