williamj has asked for the wisdom of the Perl Monks concerning the following question:

Hi I'm new to perl. I want to get the output from the following system command, I tried various things inlcuding backclick but no use, any help appreciated.  system " tar tf filename | grep gz | grep -v gz" Then pass this to another system command  system " tar xf filename (o/p from previous systemcommand) | grep ......"

Replies are listed 'Best First'.
Re: System command stdout
by thezip (Vicar) on Nov 26, 2007 at 17:39 UTC

    Welcome to PerlMonks williamj!

    It occurs to me that you might be thinking of the solution to this problem in terms of operating system calls, rather than the way that Perl shines when solving this kind of problem. Perl is great for gathering filenames via grep, and even has modules for processing tarfiles and gzips (Archive::TarGzip, for one).

    Maybe you could restate your problem in terms of the basic inputs and outputs, and then we'll help you with the Perlish way to do it.


    Your wish is my commandline.
Re: System command stdout
by moritz (Cardinal) on Nov 26, 2007 at 17:29 UTC
    You can get a command's output with the qx/.../ operator or with back ticks, see perlop for more details.
Re: System command stdout
by tuxz0r (Pilgrim) on Nov 26, 2007 at 18:51 UTC
    It looks like you want to use the manifest list from a tar package (tar -t) to tell another tar command what to archive. Is this correct? Also, your grep's in the first command line cancel each other out, picking only lines that have "gz" in them anywhere and then removing those same lines using the -v option to negate the "gz" matches (effectively leaving you with no lines of output). Provide a little more clarification on what you are trying to do and we can all possibly lend a hand.

    ---
    echo S 1 [ Y V U | perl -ane 'print reverse map { $_ = chr(ord($_)-1) } @F;'
    Warning: Any code posted by tuxz0r is untested, unless otherwise stated, and is used at your own risk.

      Wot im trying to do in perl is  tar tf file | grep gz | grep -v sig This should leave just the file.gz filename to pass to stdout Then pass this as a variable to  tar xOf file variable | grep.... I've managed to do this by passing the stdout to a tmp file and reading this in using cat, but I want to do this without using a tmp file.
        On the command line you could do,
        tar -cvf newarchive.tar `tar -tf archive.tar | grep "gz" | grep -v "si +g"`
        However, in your perl program, you could simply backtick to capture the ".gz" filename you want (using Perl's grep), and then pass that to system as the argument to the tar -cvf command. e.g.,
        my @gzfiles = grep { m/gz/ && ! m/sig/ } `tar -tf archive.tar` my @args = ( "tar","-cvf","newarchive.tar", @gzfiles ); system(@args) == 0 or die "Can't archive files: $!\n@gzfiles";

        ---
        echo S 1 [ Y V U | perl -ane 'print reverse map { $_ = chr(ord($_)-1) } @F;'
        Warning: Any code posted by tuxz0r is untested, unless otherwise stated, and is used at your own risk.

Re: System command stdout
by graff (Chancellor) on Nov 26, 2007 at 19:30 UTC
    If your objective is to create a new tar file containing a subset of files drawn from an old tar file, (e.g. just the files whose names end in ".gz"), check the man page for your tar utility (use the shell command "man tar" if your on a unix box, or maybe "info tar" on a cygwin setup). You might be able to just do a command line like this (no need for a perl script):
    tar cf new.tar --include='*.gz' @old.tar
    (That's doable with the current freebsd version of tar, which derives from GNU tar, so the latter probably supports the same sort of usage.)