4

When creating a backup using rsync --include-from=inclusion-file, the inclusion file supports wildcards, so you can put + .*rc to include all resource files in your home directory, for example.

Zip also supports inclusion files, but wildcards fail to work, so you have to enter every single filename. (I would almost say this is a bug, or weird shortcoming. Can someone shed some light?)

$ cat files
.*rc
$ ls .*rc
.ackrc  .bashrc  .mailrc
$ zip -@ out < files
    zip warning: name not matched: .*rc

Does anyone know how to make wildcards work? The only workaround I can think about is to put the wildcard patterns on the command line itself, eg. zip -@ out < files *.rc.

The question stands for all UNIX archiving tools. Zip is preferred, but not a requisite.

1
  • what's your files contents? Commented Feb 8, 2018 at 13:01

3 Answers 3

2

You could always get the shell to expand the wildcards.

With bash:

(
  shopt -s nullglob
  IFS=$'\n'
  set -- $(<files) # split+glob
  (($# == 0)) || printf '%s\n' "$@"
) | zip -@ out

With zsh (also removing duplicates with the u flag while we're at it):

print -rC1 -- ${(u)~${(f)"$(<files)"}/%/(N)} | zip -@ out

That assumes the file names don't contain newline characters.

With bsdtar:

(
  shopt -s nullglob
  IFS=$'\n'
  set -- $(<files) # split+glob
  (($# == 0)) || printf '%s\0' "$@"
) | bsdtar --null --format zip -T - -cf out.zip

zsh:

print -rNC1 -- ${(u)~${(f)"$(<files)"}/%/(N)} |
  bsdtar --null --format zip -T - -cf out.zip

With bsdtar, you could also use more modern/useful archive formats than infozip's).

This time it's fine if file names contain newlines (though obviously the pattern themselves can't as there's one per line of files with no way to escape it).

Note that both shells have extensions over the standard shell wildcard operators (the list of which varies with the shells and the enabled glob options for each).

1

7z (from 7-zip) will use wildcards in the list file (and can create ZIP-format files, in addition to its own).

4
  • Not bad, though 7z is not a standard UNIX tool; it must be installed manually. Commented Feb 8, 2018 at 13:28
  • Available from the repos in most distros: ask.xmodulo.com/install-7zip-linux.html Commented Feb 8, 2018 at 15:50
  • Sure. I'd rather just stick with stuff that comes out of the box on any distro: 1 gzip 2 gunzip 3 zcat 4 gzcat 5 tar 6 cpio 7 pax 8 bzip2 9 zip 10 compress en.wikibooks.org/wiki/Guide_to_Unix/Commands/File_Compression Commented Feb 8, 2018 at 16:46
  • 1
    @forthrin, zip is not a standard UNIX tool either. Commented Jul 19, 2020 at 9:26
1

You seem to be right in your assessment of zip's option -@ requiring literal filenames. The documentation I have goes on to say:

Under Unix, this option can be used to powerful effect in conjunction with the find (1) command. For example, to archive all the C source files in the current directory and its subdirectories:

find . -name "*.[ch]" -print | zip source -@

Could this be enough for your needs? In the simple case where you want to archive all files from the current directory matching .*rc, just zip out .*rc should do (as you mentioned); if you need to consider all such files recursively in subfolders, adapting the above find command could do:

find . -name '.*rc' | zip -@ out

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.