93

First the specific problem: In linux, I use zcat to list a .zip file. In osx, zcat seems to automatically append .Z to the file name. Various people suggest replacing zcat with gzcat; however, gzcat complains that the file is not in gzip format!

'file ' shows this: ...Zip archive data, at least v2.0 to extract

So neither zcat or gzcat will work in osx, what can I do?

I have a medium sized script in in bash which uses, zcat/gzcat, sed awk and other basic utilities to process a number of files. I'd like to duplicate that environment on my osx laptop so I can work offline. Any general suggestions how I can avoid such pain? I expect this is a fairly routine workflow so must have been sorted out by others.

user23398
  • 1,281

8 Answers8

158

You are right. It's annoying behavior.

$ zcat foo.txt.gz 
zcat: can't stat: foo.txt.gz (foo.txt.gz.Z): No such file or directory

Try this:

$ zcat < foo.txt.gz 
asdfadsf
vy32
  • 2,208
39

I know this is an old question. However, I found a solution from an even older github thread.

You can simply use gunzip -c that works similar to zcat without the errors on Mac OS X.

$ gunzip -c 20150707_backup.sql.gz | mysql -u mysql_user -p
dakdad
  • 491
  • 4
  • 4
22

You can install GNU utils for Mac OS X, e.g., using homebrew (run brew install coreutils gnu-sed, which installs gzcat et al. and gsed). This will provide you with the GNU implementation of each command.

Then, to make your life easier, make a variable for each command (e.g. sed=gsed, and use $sed subsequently), or simply alias them (e.g. alias sed=gsed) in any script you write. I've written a Gist on this for your convenience: gnu-tools-for-mac.sh. Put (or include) this code on top of your scripts.

Use the GNU implementation for both compressing and extracting the archives. I'd say you can't mix the uses of the OS X and GNU implementation.

Peterino
  • 445
18

I just gave this a try and found something very interesting! For gz files, we are expected to run gzcat on Mac OS.

Solution 1

  • Use gzcat /path/to/file.gz and it should work.
  • Using zcat /path/to/file.gz will give you an error.

Solution 2

  • Pipe in the file to zcat and it will work.
  • For example, cat /path/to/file.gz | zcat will work.

I hope this helps!

Jigarius
  • 426
3

Instead of

zcat filename.gz | grep "hello"

Use

gunzip -c filename.gz | grep "hello"
Geek
  • 131
1

As reported in https://stackoverflow.com/a/296725/4725074

Using gzcat instead of zcat solved my issue.

Vzzarr
  • 171
0

The Mac OS X version of gzip(1) doesn't support reading zip files. From the man page:

This version of gzip is also capable of decompressing files compressed using compress(1) or bzip2(1).

But the Linux (GNU) version does.

gunzip can currently decompress files created by gzip, zip, compress, compress -H or pack.

Third parties have packaged GNU gzip for Mac OS X; you can find these from a web search. That is probably the path of least resistance.

Michael Hampton
  • 252,907
0

Funny, I had the same issue when executing a bash-script, bash somescript.sh, which executed a for-loop with gzcat inside it. But trying these things inside the somescript.sh-script ...:

  1. zcat < file.txt.gz
  2. I had installed brew install coreutils already, but nonetheless, re-installed: brew reinstall coreutils
  3. gunzip -c file.txt.gz

... amounted to nothing...

But I also used a reference to a directory:

SOMEDIR="~/DIR1/DIR2/DATA"

Which is interpreted as ~/DIR1/DIR2/DATA and apparently doesn't work within the bash-script within macOS. This worked:

SOMEDIR="${HOME}/DIR1/DIR2/DATA"

Which is interpreted as /Users/someuser/DIR1/DIR2/DATA. I don't know why - I'm not an expert macOS-BASH-techie - but it worked in conjunction with my original code ...

gzcat file.txt.gz | awk '{ print $1, $2, $3, $4, $5, $6 }' > ${SOMEDIR}/new.file.txt.

... within my somescript.sh-script.

Maybe it's useful to someone.

Best,

Sander