diff options
author | EuAndreh <eu@euandre.org> | 2022-10-19 11:43:29 -0300 |
---|---|---|
committer | EuAndreh <eu@euandre.org> | 2022-10-19 11:50:56 -0300 |
commit | a8358c4809e3deaeaeff46c90f86d3aaac6b4354 (patch) | |
tree | 0003fbce4bf4057190040724e947a4678b971b20 /bin/z | |
parent | etc/guix/home.scm: Add lzop compression utility (diff) | |
download | dotfiles-a8358c4809e3deaeaeff46c90f86d3aaac6b4354.tar.gz dotfiles-a8358c4809e3deaeaeff46c90f86d3aaac6b4354.tar.xz |
bin/z: Add working utility
Pilfer initial version of manpage from zrun.
Diffstat (limited to 'bin/z')
-rw-r--r-- | bin/z | 153 |
1 files changed, 153 insertions, 0 deletions
@@ -0,0 +1,153 @@ +#!/usr/bin/env perl + +use v5.34; +use warnings; +use feature 'signatures'; +no warnings qw(experimental::signatures); +use Getopt::Std (); +use File::Temp (); +use File::Basename (); +use List::Util qw(any); + + +sub usage($fh) { + print $fh <<~'EOF' + Usage: + z COMMANDS... + z -h + EOF +} + +sub help($fh) { + print $fh <<~'EOF' + + + Options: + -h, --help show this message + + + Wrapper that uncompresses file arguments to commands. + This enables having commands that operate on plain files to not + need to know if they're compressed or not. + + It doesn't depend on the file extension, but on what file(1) says + of it. + + + Examples: + + Replacement for zcat(1p): + + $ z cat a-file.gz + + + Transparent grep (where my-file.dat is xz compressed): + + $ z grep -E '[a-z]+' my-file.dat + EOF +} + +for (@ARGV) { + last if $_ eq '--'; + if ($_ eq '--help') { + usage *STDOUT; + help *STDOUT; + exit; + } +} + +my %opts; +if (!Getopt::Std::getopts('h', \%opts)) { + usage *STDERR; + exit 2; +} + +if ($opts{h}) { + usage *STDOUT; + help *STDOUT; + exit; +} + + +# Transform +# FILENAME: content/type; charset=some\n +# into +# content/type +sub trim($x) { + chomp $x; + $x =~ s/^.*?: //; + $x =~ s/;.*$//; + return $x; +} + +my %TYPES = ( + 'application/gzip' => [qw(gzip -dc)], + 'application/x-bzip2' => [qw(bzip2 -dc)], + 'application/x-xz' => [qw(xz -dc)], + 'application/x-lzma' => [qw(lzma -dc)], +); + +my @tmpfiles; +sub arg_for($arg) { + if (! -e $arg) { + return $arg; + } + + my $type = trim `file -i $_`; + if (any { $type eq $_ } keys %TYPES) { + my $template = File::Basename::basename $arg . '.XXXXXX'; + my ($fh, $tmpname) = File::Temp::tempfile(TEMPLATE => $template); + push @tmpfiles, $tmpname; + my @command = @{$TYPES{$type}}; + print $fh `@command $arg`; + die $! if $?; + close $fh; + return $tmpname; + } + + return $arg; +} + +sub status_for($n) { + if ($n == -1) { + return 127; + } elsif ($n & 127) { + return $n & 127; + } else { + return $n >> 8; + } +} + +my @CMD = map { arg_for $_ } @ARGV; +exit status_for(system @CMD); + +END { + unlink @tmpfiles; +} + + +__END__ + +=head1 NAME + +z - Wrapper that uncompresses file arguments to commands. + +=head1 SYNOPSIS + +z COMMAND FILE... + +=head1 DESCRIPTION + +Prefixing a shell command with "zrun" causes any compressed files that are +arguments of the command to be transparently uncompressed to temp files +(not pipes) and the uncompressed files fed to the command. + +This is a quick way to run a command that does not itself support +compressed files, without manually uncompressing the files. + +The following compression types are supported: gz bz2 Z xz lzma lzo + +If zrun is linked to some name beginning with z, like zprog, and the link is +executed, this is equivalent to executing "zrun prog". + +=cut |