38

I have many files I need to zip into a single directory. I don't want to zip all the files in the directory, but only ones matching a certain query.

I did

grep abc file-* > out.txt 

to make a file with all the instances of "abc" in each file. I need the files themselves. How can I tell bash to zip only those files?

3
  • Wildcards does not work? Why? If I can ask...
    – jherran
    Nov 2, 2014 at 15:15
  • @jherran I don't want to zip all the files in the directory, only ones matching a certain query. I did grep abc file-* > out.txt to make a file with all the instances of "abc" in each file. I need the files themselves. Nov 2, 2014 at 15:18
  • What @jherran means is zip ZipFile.zip file-*, which is the obvious way to do it. You would need an intermediate file only if you were using a complex find or a concatenation of file lists from different searches.
    – AFH
    Nov 2, 2014 at 18:07

2 Answers 2

59

Very simple:

zip archive -@ < out.txt

That is, if your out.txt file contains one filename per line. It will add all the files from out.txt to one archive called archive.zip.

The -@ option makes zip read from STDIN.

If you want to skip creating a temporary out.txt file, you can use grep's capability to print filenames, too. -r enables recursive search (might not be necessary in your case) and -l prints only filenames:

grep -rl "abc" file-* | zip archive -@
5
  • Works nicely, except I have a list file where there are spaces in file names. I tried both escaping them with `` and not escaping them, once in quotes and once without quotes around the file name (one line - one file name). Nothing worked so far.
    – Thomas W.
    Dec 16, 2015 at 7:03
  • 2
    I made it work with ` \ ` escaped spaces and no quotes in the file and the following: cat out.txt | while read line ; do xargs zip archive.zip $line ; done
    – Thomas W.
    Dec 16, 2015 at 7:50
  • 1
    if you want to zip files with similar names you could try zip archive.zip $(ls common_name*)
    – chepe263
    Feb 9, 2017 at 17:08
  • @chepe263 This breaks if files have spaces in their path. It's generally discouraged to parse ls output.
    – slhck
    Feb 10, 2017 at 7:45
  • 2
    For anyone else on a mac who wound up here courtesy of search engine indexing, the -@ option syntax works fine as of 10.16, even though the man page still includes language about not on MacOS Feb 10, 2020 at 19:48
5

Alternatives to the accepted answer, from here:

cat out.txt | zip -@ zipfile.zip
cat out.txt | zip -@ - > zipfile.zip
zip zipfile.zip $(cat out.txt) -r
zip zipfile.zip -r . [email protected]
1
  • I like the first one. Worked well for me. The last one did not seem to work well - took too long, so I ctrl-c'd out of it. Aug 28, 2023 at 21:15

You must log in to answer this question.

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