11

I want to list members of tar files verbosely, and show the file size in human-readable format not in bytes, does the tar has the option to do this?

zhenguoli
  • 263

3 Answers3

12

There's no built-in tar option, but you can filter its output. For example, using humanize:

#!/usr/bin/env python

import fileinput
import humanize

for line in fileinput.input():
    (perm, owner, size, date, time, filename) = tuple(line.split())
    print '{0} {1} {2:>9} {3} {4} {5}'.format(perm, owner, humanize.naturalsize(size, gnu=True), date, time, filename)

Save this as e.g. humantvf, then

tar tvf ... | ./humantvf
Stephen Kitt
  • 434,908
4

You could use awk together with numfmt:

tar --list --verbose --file myfiles.tar.gz | \
    awk '{ \
        "numfmt --to=iec-i --format=%7.f --suffix=B " $3 | getline x; \
        $3=x; \
        print $0 \
    }'

This modifies the third column (i.e. the file size column), replacing the number of bytes with a human readable size obtained from numfmt.

Result:

-rw-r--r-- user/user   16KiB 2020-01-01 12:34 pics/camel.jpg
-rw-r--r-- user/user    2KiB 2019-12-01 12:34 pics/cat.jpg
-rw-r--r-- user/user  410KiB 2019-12-01 12:34 pics/panda.jpg
-rw-r--r-- user/user    2KiB 2019-12-01 12:34 pics/unicorn.gif
# ...

Note that numfmt is specific to GNU coreutils. It has been available since GNU coreutils 8.21 (released at the beginning of 2013).

Flux
  • 2,938
  • 4
    Inspired by @Flux, with GNU coreutils 8.30, perhaps we can just use numfmt, like tar -zvtf myfiles.tar.gz | numfmt --field=3 --to=iec-i --suffix=B, to handle invalid fields, just appending the option --invalid=ignore. – Quar Sep 13 '20 at 22:21
  • I can confirm this did work for me as a oneliner with no awk, tar tvzf file.tar | numfmt --field=5 --to=si The program passed through the other fields. And even better news, it was already present in my minimal cygwin. – davenpcj Feb 14 '24 at 16:52
3

The solution for making this human readable AND sorting by size was given by @Quar and @Peter. This only prints out the file and size, however you can add more by adding to the print statement in awk - for example this adds the file name as well:

tar -tvf $1 \
  | numfmt --field=3 --to=iec-i --suffix=B \
  | awk -v size="$size" '$3 >= size {print $3" "$6}' \
  | sort -hr \
Arcsector
  • 131
  • 3