5

I have a bunch of .jpg.gz files in a directory that I need to decompress.

I know that the decompress command is:

tar -xzvf FileNameHere.jpg.gz

But is there a flag that you can recursively uncompressed the files in a directory? I have over a hundred compressed files and I don't want to manually decompress every single one.

Also since I am SSHing into an hosting service I only have the following commands to use:

arch
bzip2
cal
cksum
cmp
cp
crontab
basename
cd
chmod
ls
date
df
du
dos2unix
unix2dos
file
getfacl
gzip
head
hostid
tail
mkdir
mv
nslookup
sdiff
tar
uptime
wget
whois
unzip
  • 1
    tar is used to create or unpack archives. An archive is a collection of several files, and may also contain a directory-structure. Often archives are compressed - usually with gzip (.tar.gz), bzip2 (.tar.bz2) or xz(.tar.xz) - but the compression/uncompression is done with separate programs... tar however, can call these programs seamlessly (when given the z, j, or J option). Your files are not tar-archives, but gziped files - to uncompress, simply use gunzip (or gzip -d. JPG is a compressed format, so it's usually redundant to compress it again. – Baard Kopperud May 11 '16 at 17:49
  • When you say SSHing into an hosting service do you mean you do not have an interactive shell, but rather can only just do ssh foo@host <comand>? – rrauenza May 11 '16 at 18:31
8

To extract your files, you need to use gzip:

gzip -d *.jpg.gz

You mention doing this recursively; given that you don't have find, you'll have to visit each directory in turn and run the above command.

  • Does anyone know if it makes a difference if the files have the extension .jpg.gz? – Fortuna Iwasaki May 11 '16 at 16:23
  • Really sorry about that, but I only saw that extension now. Also I should make it known that I am using an SSH terminal on a hosting service and can't use gunzip – Fortuna Iwasaki May 11 '16 at 16:30
  • And Stephen added the -d parm to gzip to decompress the file – Mark Stewart May 11 '16 at 16:49
8

If shell of the host you are sshing to is bash version >= 4.0, you can enable the globstar option. When enabled, the ** glob will recursively match subdirectories. So the following should do what you need:

shopt -s globstar
for gz_file in **/*.jpg.gz; do
    gzip -d "$gz_file"
done

No manual recursing into subdirectories required.

3

While a shell script could be written to recurse the directories (but I don't think you have access to a remote sh), you could use this crude but effective shortcut, assuming your remote restricted ssh does wildcard expansion:

gzip -d *.jpg.gz
gzip -d */*.jpg.gz
gzip -d */*/*.jpg.gz
...

...depending on the depth and size of the subdirectories.

Note: If you have too many files, you can end up exceeding the command line length limit

edit: This used to include an answer using ls -R, but that doesn't provide full paths.

  • As written, the grep and cat run locally, so the entire ls output has to go over the network to be filtered by a local grep. – Peter Cordes May 12 '16 at 1:29
  • 1
    Correct. Note that the OP doesn't have a remote grep. – rrauenza May 13 '16 at 21:36
  • ah, of course. It's worth considering a shell loop on the remote side for the text processing. ls -R | IFS= while read fn; do [ "x$fn" = "x*.gz" ] && gzip -d "$fn";done. If I got that right, it should work with POSIX sh, no bash required. It also handles anything except \n in filenames. I forget if glob matching works that way; you might have to check for a trailing .gz with [ "x${fn%.gz}" != "x$fn" ] or something. – Peter Cordes May 13 '16 at 21:51
  • You will notice that the OP doesn't have a shell in the list of available commands - I wasn't sure if that means restricted ssh that doesn't start off with a shell, but rather just an execve() of the command given on the ssh command line. – rrauenza May 13 '16 at 21:56
  • 1
    Did this work for anyone? Every ls -R (with nontty stdout) I've seen puts the directorypath on one line and the contained filenames (only) on subsequent lines, so I need to recombine with something like ls -R | awk '/:$/{dir=substr($0,1,length()-1)} /[.]jpg[.]gz$/{print dir $0}' >pathnamesforgzipd Alternatively select only the dirnames and add /*.jpg.gz and let those be globbed. – dave_thompson_085 May 14 '16 at 2:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.