Optimizing your experience
unsplashunsplash
Gradient background

Using the tar Command in Linux

Clarice Bouwer

Software Engineering Team Lead and Director of Cloudsure

Monday, 14 January 2019 · Estimated 6 minute read

I used to right-click on a zipped file and manage the archive using the GUI. Gone are those days. Now I mainly work with tar files and need a cheat sheet to remember the commands for the terminal. 😊 You can find that at the end of this post.


This post forms part of a sequence of command line references that I will be writing where I forget the command or its syntax or find it interesting enough to document it.

Although it is easily Google-able, there are usually a chain of commands that I want kept together for ease of use.

The commands I use should be universal but just in case, I am running Fedora release 28 (Twenty Eight) and Zsh.

Also, if you want to contribute something interesting in any of my posts, please create a pull-request or write a comment below. 😄


Original post: 9 Jan 2019 Update: Covers the extraction of files without extracting the entire tar


As far as I understand, tar files typically have the tar or tar.gz extensions. tar is the archive that can preserve permissions and directory structures and tar.gz is the compressed gzip-ed tar file.

Listing the contents of an archive

You can list the contents of an archive tar -tf archive.tar.gz without having to extract the data. When you want to see more information tar -tvf archive.tar.gz prints out details about the file including the permissions, owner, group, file size, modified date and time and the filename.

Your can also run these commands as tar --file archive.tar.gz --list and tar --list --file archive.tar.gz --verbose

What are all these switches?

  • t | -- list: tells tar to list everything in the archive
  • v | -- verbose: verbose (optional), prints out as much information as it can for you
  • f | -- file: specifies the file of the archive you want to list. (This must always be the last flag as it precedes the filename in the command unless you use --file)

Creating a new archive

Archive

Create a new archive for the awesome directory tar -cf archive.tar awesome or tar --create --file awesome. You can create an archive from any working directory tar -cf archive.tar /home/user/workspace/awesome

tar -cvf archive.tar awesome or tar --create --verbose --file awesome will print out the files names that have been added to the archive.

Compressed archive

The same switches apply as above, however we include the -z or --gzip switches to indicate that the archive must be compressed.

Create a compressed gzip tar archive tar -cvzf archive.tar.gz awesome.json or tar --create --verbose --gzip --file archive.tar.gz awesome.json for the awesome.json file.

Create a compressed gzip tar archive tar -cvzf archive.tar.gz /path/to/awesome for the /path/to/awesome directory.

If you want to archive and compress multiple members, chain the files and directories tar -cvzf archive.tar.gz /path/to/something another/awesome somewhere/sauce.json

Exclusions

In cases where you need to omit specific files or directories from an archive tar -czvf archive.tar.gz --exclude=\*.gz /path/to/awesome will exclude any files with the .gz extension when creating the archive on path /path/to/awesome.

To exclude multiple files and directions, exclusions can be chained tar -czvf archive.tar.gz --exclude=something.tar --exclude=somewhere /path/to/awesome The archive on path /path/to/awesome is created which excludes the something.tar file and somewhere directory.

What are all these switches?

  • c | --create: tells tar to create a new archive
  • v | --verbose: verbose (optional), prints out as much information as it can for you
  • z | --gzip: compresses the archive using gzip (you can also use -j | --bzip2 for bzip2 compression)
  • f | --file: specifies the file of the archive name that you want to create. (This must always be the last flag as it precedes the file name in the command unless you use the --file switch)
  • --exclude: exclude files given as a pattern

Clean up

Sometimes I need to clean up files in a directory once I have created the archive. An example is one of my logs directories. Once I have archived all the logs, I want to delete them but keep my archive and any existing archives. Using Zsh I run

Copy
# In Zsh, you can use ^ to negate
# a pattern with extendedglob enabled
setopt extendedglob
rm -- ^*.tar.gz

Updating an archive

tar cannot update compressed archives so you need to create an uncompressed archive. The -u or --update switch will append files newer than the copy in the archive.

Copy
# Create a new archive without compression
tar -cvf archive.tar /path/to/archive
# Update or add files in /path/to/archive
# tar will update and changed or added files
tar -uvf archive.tar /path/to/awesome
# You can then compress your archive
gzip archive.tar.gz

Extracting data

Extract data tar -xf archive.tar or tar --extract --file archive.tar to its local directory.

Extract a compressed archive tar -xvzf archive.tar.gz to its local directory. This extracts the files and decompresses them using gzip.

Extract a compressed archive to another directory tar -xvzC /path/to/awesome -f sauce.tar The files in sauce.tar.gz are extracted to /path/to/awesome

What are all these switches?

  • x | extract: tells tar to extract the files from the archive
  • v | --verbose: verbose (optional), prints out as much information as it can for you
  • z | --gzip: tells tar to decompress the archive using gzip - you can use j | --bzip2 for bzip2
  • C | --directory: change to directory
  • f | --file: specifies the file of the archive you want to extract. (This must always be the last flag as it precedes the filename in the command)

Extracting specific files

You don't have to extract the entire file. If you have a tar file but are only interested in a few files then grab them out of the tar file:

  1. List the contents of the tar file tar -ztvf archive.tar.gz | grep filename and look for the file name(s) you are interested in.

  2. Extract the file tar -zxvf archive.tar.gz ./awesome.clj or directory tar --extract --file=archive.tar.gz src

Extracting wildcards

If you can't use a rigid file name or directory then you can use wildcards (globbing patterns) tar -xf archive.tar --wildcards --no-anchored "*.clj"

--wildcards tells tar to accept globbing patterns while --no-anchored tells it that the pattern applies to the member names after any / delimiter.

Comparing against the file system

-d, --diff, --compare finds the differences between the archive and the file system. The arguments are optional and you specify archive members to compare. If not given, the current working directory is assumed.

This is handy when you want to see whether there are files in the tar file that are not yet in the local filesystem or visa versa. It also reports differences in attributes including the file size, mode, owner, modification date and contents.

The following example compares the archive members 'rock', 'blues' and 'funk' in the archive 'bluesrock.tar' with files of the same name in the file system. (Note that there is no file, `funk'; tar will report an error message.)

Copy
# this section and example was found at gnu.org
# http://www.gnu.org/software/tar/manual/html_node/compare.html
tar --compare --file=bluesrock.tar rock blues funk
rock
blues
tar: funk not found in archive

Using zip

This is outside the scope of this post but I have the base commands available for in case I need them.

To list the contents of the archive without unzipping it less file.zip or unzip -l file.zip.

To create a new archive zip file.zip file1 file2 file3 or for a directory zip -r file.zip /path/to/archive.

To exclude files from an archive being created zip -9 -r --exclude='*.zip' file.zip /path/to/archive.

To unzip the archive unzip file.zip.

Cheat sheet

List

Copy
tar -tf archive.tar.gz
tar -tvf archive.tar.gz

Create

Archive

Copy
tar -cvf archive.tar file1 file2 file3

Compressed archive

Copy
tar -cvzf archive.tar.gz file1 file2 file3

Exclusions

Copy
tar -czvf archive.tar.gz --exclude=\*.gz file1 file2 file3
tar -czvf archive.tar.gz --exclude=\*.gz --exclude=file\* file1 file2 file3

Exclusion files except some

Copy
setopt extendedglob
rm -- ^*.tar.gz

Update

Copy
tar -cvf archive.tar /path/to/archive
tar -uvf archive.tar member/director
gzip archive.tar

Extract

Archive

Copy
tar -xvf archive.tar

Compressed

Copy
tar -xvzf archive.tar.gz
tar -xvC directory -f archive.tar

Compare / Diff

Copy
tar --compare --file=archive.tar file1 file2 file3

Zip

Copy
less archive.zip
unzip -l archive.zip
zip archive.zip file1 file2 file3
zip -r archive.zip /path/to/archive
zip -9 -r --exclude='*.zip' archive.zip /path/to/archive
unzip archive.zip

References