77

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,111
  • 3
  • 9
  • 14
  • 2
    If it's Zip archive data, it's **not** in gzip format! – Michael Hampton Jan 27 '14 at 00:48
  • @MichaelHampton I can zcat on linux fine. Neither zcat nor gzcat works on osx. So how can I resolve this? Is there another set of utilities I can install which will work both on linux as well as osx? These scripts are my own so I can change them (although I'd like to keep them simple). I control both linux/osx environments as well so I can do simple installs on both as well. – user23398 Jan 27 '14 at 03:25
  • I wouldn't say it's routine. I generally use `zip` to deal with zip files, not `gzip`. – Michael Hampton Jan 27 '14 at 03:39

7 Answers7

140

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,018
  • 1
  • 15
  • 20
34

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
  • 441
  • 4
  • 4
17

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
  • 385
  • 3
  • 7
  • 3
    You can alternatively add `/usr/local/opt/coreutils/libexec/gnubin` to your `PATH`, which will make them available without the `g` prefix. – bfontaine Jul 07 '14 at 17:56
12

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
  • 306
  • 3
  • 5
1

Instead of

zcat filename.gz | grep "hello"

Use

gunzip -c filename.gz | grep "hello"
Geek
  • 111
  • 1
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
  • 237,123
  • 42
  • 477
  • 940
  • Searching the web and installing new software is *never* the path of least resistance. – vy32 Oct 11 '17 at 04:25
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