How to find and tar files into a tar ball

I would like to find all documents file *.doc and create a tarball of those files and store in /nfs/backups/docs/file.tar. Is it possible to find and tar files on a Linux or Unix-like system?

The find command used to search for files in a directory hierarchy as per given criteria. The tar command is an archiving utility for Linux, macOS, FreeBSD/OpenBSD/NetBSD and Unix-like system to create tarballs. Let us see how to combine tar command with find command to create a tarball in a single command line option.
How to find and tar files on linux unix

ADVERTISEMENTS

Find command syntax

The syntax is:
find /path/to/search -name "file-to-search" -options
## find all Perl (*.pl) files ##
find $HOME -name "*.pl" -print
## find all *.doc files ##
find $HOME -name "*.doc" -print
## Safe search options for xargs or tar ##
find /path/to/dir/ -name "*.jpg" -print0
## find all *.sh (shell scripts) and run ls -l command on it ##
find . -iname "*.sh" -exec ls -l {} +

Sample outputs from the last command:

-rw-r--r-- 1 vivek vivek 1169 Apr  4  2017 ./backups/ansible/cluster/nginx.build.sh
-rwxr-xr-x 1 vivek vivek 1500 Dec  6 14:36 ./bin/cloudflare.pure.url.sh
lrwxrwxrwx 1 vivek vivek   13 Dec 31  2013 ./bin/cmspostupload.sh -> postupload.sh
lrwxrwxrwx 1 vivek vivek   12 Dec 31  2013 ./bin/cmspreupload.sh -> preupload.sh
lrwxrwxrwx 1 vivek vivek   14 Dec 31  2013 ./bin/cmssuploadimage.sh -> uploadimage.sh
lrwxrwxrwx 1 vivek vivek   13 Dec 31  2013 ./bin/faqpostupload.sh -> postupload.sh
lrwxrwxrwx 1 vivek vivek   12 Dec 31  2013 ./bin/faqpreupload.sh -> preupload.sh
lrwxrwxrwx 1 vivek vivek   14 Dec 31  2013 ./bin/faquploadimage.sh -> uploadimage.sh
-rw-r--r-- 1 vivek vivek  778 Nov  6 14:44 ./bin/mirror.sh
-rwxr-xr-x 1 vivek vivek  136 Apr 25  2015 ./bin/nixcraft.com.301.sh
-rwxr-xr-x 1 vivek vivek  547 Jan 30  2017 ./bin/paypal.sh
-rwxr-xr-x 1 vivek vivek  531 Dec 31  2013 ./bin/postupload.sh
-rwxr-xr-x 1 vivek vivek  437 Dec 31  2013 ./bin/preupload.sh
-rwxr-xr-x 1 vivek vivek 1046 May 18  2017 ./bin/purge.all.cloudflare.domain.sh
lrwxrwxrwx 1 vivek vivek   13 Dec 31  2013 ./bin/tipspostupload.sh -> postupload.sh
lrwxrwxrwx 1 vivek vivek   12 Dec 31  2013 ./bin/tipspreupload.sh -> preupload.sh
lrwxrwxrwx 1 vivek vivek   14 Dec 31  2013 ./bin/tipsuploadimage.sh -> uploadimage.sh
-rwxr-xr-x 1 vivek vivek 1193 Oct 18  2013 ./bin/uploadimage.sh
-rwxr-xr-x 1 vivek vivek   29 Nov  6 14:33 ./.vim/plugged/neomake/tests/fixtures/errors.sh
-rwxr-xr-x 1 vivek vivek  215 Nov  6 14:33 ./.vim/plugged/neomake/tests/helpers/trap.sh

Tar command syntax

To create a tar ball of /home/vivek/projects directory, run:
$ tar -cvf /home/vivek/projects.tar /home/vivek/projects

Combining find and tar commands so that we can find and tar files into a tarball

Again the syntax is:
find /dir/to/search/ -name "*.doc" -exec tar -rvf out.tar {} \;
OR
find /dir/to/search/ -name "*.doc" -exec tar -rvf out.tar {} +
For example:
find $HOME -name "*.doc" -exec tar -rvf /tmp/all-doc-files.tar "{}" \;
## OR ##
find $HOME -name "*.doc" -exec tar -rvf /tmp/all-doc-files.tar "{}" +

Where, find command options:

  • -name "*.doc" : Find file as per given pattern/criteria. In this case find all *.doc files in $HOME.
  • -exec tar ... : Execute tar command on all files found by the find command.

Where, tar command options:

  • -r : Append files to the end of an archive. Arguments have the same meaning as for -c option.
  • -v : Verbose output.
  • -f : out.tar : Append all files to out.tar file.

How to find files and tar them with special characters in file names such as white spaces

Let us see safe option to deal with file names such as:

-rw-rw-r-- 1 vivek vivek 12 Oct 28 11:38 'Hello    World    .sh   '
-rw-rw-r-- 1 vivek vivek 18 Oct 28 11:32 'this ? *is a test.sh'
-rw-rw-r-- 1 vivek vivek 18 Oct 28 11:32 'this is a test.sh'

So far we leaned how to pipe output of the find command to the tar command as follows:
find $HOME -name "*.doc" -print0 | tar -cvf /tmp/file.tar --null -T -
However, above command will fail when it see weird and special filenames. The -print0 option passed to the find command deals with special file names such as white spaces or wild characters in file names. The --null and -T - option tells the tar command to read its input from stdin or pipe. Now will use use the xargs command:
find $HOME -type f -name "*.sh" -print0 | xargs -0 tar cfvz /nfs/x230/my-shell-scripts.tgz
Where,

  • -print0 : Let us print the full file name on the standard output (screen), followed by a null character (instead of the newline character that -print uses) with the find command. This allows file names that contain newlines or other types of white space to be correctly interpreted by programs that process the find output. This option corresponds to the -0 option of xargs.
  • -0 or --null : Input items are terminated by a null character instead of by whitespace, and the quotes and backslash are not special (every character is taken literally). Disables the end of file string, which is treated like any other argument. Useful when input items might contain white space, quote marks, or backslashes. The GNU find -print0 option produces input suitable for this mode.

Thus, it would be best if you always used the last syntax. In other words:
find /path/ -name "file-pattern" -print0 | xargs -0 tar cfz tarball.gz

Conclusion

You learned how to search and tar files on fly safely on your Linux or Unix-like systems. See the following man pages for more info:
$ man tar
$ man find
$ man xargs
$ man bash

Also read Unix command to find a file in a directory and subdirectory.

🐧 If you liked this page, please support my work on Patreon or with a donation.
🐧 Get the latest tutorials on SysAdmin, Linux/Unix, Open Source/DevOps topics:
CategoryList of Unix and Linux commands
File Managementcat
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network Utilitiesdig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04

ADVERTISEMENTS
3 comments… add one
  • Bodo Dec 17, 2017 @ 9:06

    I think you should put more emphasis on handling special characters in file names, e.g. spaces. Personally I would have suggested the bottom-most approach using xargs, but to avoid errors -print0 should be used here too, in combination with the -0 / --null argument of xargs.

  • Mohamed Hosafy Oct 27, 2020 @ 14:04

    Using the pipe option and the -T will lead to an empty tar file in case the find comes empty which is probably not a desired outcome.

    • 🐧 Vivek Gite Oct 28, 2020 @ 6:16

      Hi,

      I tested it on the GNU/Linux find and it cowardly refusing to create an empty archive:
      find $HOME -type f -name "*.foobar" -print0 | xargs -0 tar cfvz /tmp/test.tar.gz
      Here is what I got:

      tar: Cowardly refusing to create an empty archive
      Try 'tar --help' or 'tar --usage' for more information.
      

      However, this might not work on BSD/tar or Solaris/HP-UX/AIX tar. YMMV.

Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre>, <code>...</code> and <kbd>...</kbd> for code samples.