Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

System(), writing to a new file

by cyates (Novice)
on Jul 17, 2013 at 21:23 UTC ( #1044908=perlquestion: print w/replies, xml ) Need Help??
cyates has asked for the wisdom of the Perl Monks concerning the following question:

Hello everyone, I'm sorting a document numerically, and then want that document to be written to a new file. The UNIX sort command works very well so I used:

#!/usr/bin/perl use strict; use warnings; my $file = 'somefile.txt'; my @args = ("sort", $file); system(@args) == 0 or die "sytem @args failed: $?";
Which gives me a nice print out of my sorted document to the terminal screen. I want to write this to a new document and know you can use the UNIX command  sort filename > newfilename   to easily do this, but I can't seem to figure out how to make Perl input this command. Using
my @args("sort" "somefile.txt" "somefile2.txt"); system(@args) == 0 or die "system @args failed: $?";
outputs two sorted documents, or gives the error the second file does not exist (if I am trying to create a new one)

Replies are listed 'Best First'.
Re: System(), writing to a new file
by mtmcc (Hermit) on Jul 17, 2013 at 23:28 UTC
    This might be system dependent, but backticks work for me:

    #!/usr/bin/perl use strict; use warnings; my $file = 'somefile.txt'; my @args = ("sort", $file); open (my $out, ">", "outputfile.txt"); print $out `@args` or die "system @args failed: $?";

      Load all of the output of sort(1) to perl's memory, just to write it out to the file right after? Hardly efficient.

      As mentioned below, system(@list) doesn't invoke the shell. This is usually a good thing, but in this case the shell redirection the OP is expecting won't work. system($string) invokes the shell. Hence, system("sort $infile > $outfile") will work.

      However, there's a better approach: Use the -o flag to sort(1), like this: @args = 'sort', '-o', $outfile, $infile; system(@args);

        Perfect. Thank you
Re: System(), writing to a new file
by Laurent_R (Canon) on Jul 17, 2013 at 22:37 UTC

    Hmm, if the whole point of your Perl script is to launch a shell sort, then maybe you should consider a shell script instead.

    The alternative is to load the file into an array, and use the Perl sort comand to sort the array (assuming the file is not too large for your available memory).

    But I don't see any interest in using Perl to launch a shell command in your context.

      Files are GB sized
        shouldn't make any difference
Re: System(), writing to a new file
by zork42 (Monk) on Jul 18, 2013 at 07:18 UTC
    I am not sure about this, but are you able to redirect the output?
    system("sort somefile.txt >somefile2.txt") or die;
    If I've remembered my unix syntax, the following will send any error messages (on STDERR) to the file "error.txt"
    system("sort somefile.txt >somefile2.txt 2>error.txt") or die;
    IIRC you must use the single argument version of system() for redirections to work. (I think the multiple argument versions bypass the shell.) I'd check this though!
      I saw there was no redirection in the OP's code. That's why I suggested redirection in my post.
      But I missed the sort filename > newfilename comment in the OP text.
Re: System(), writing to a new file
by zork42 (Monk) on Jul 19, 2013 at 15:16 UTC
    Using the sort -o flag from Anonymous Monk's post...

    You might want to consider this:
    my $error_message = `sort -o $outfile $infile 2>&1`
    The "2>&1" bit redirects errors on STDERR to STDOUT, and the latter will be saved in $error_message.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1044908]
Approved by ww
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (3)
As of 2018-07-19 19:26 GMT
Find Nodes?
    Voting Booth?
    It has been suggested to rename Perl 6 in order to boost its marketing potential. Which name would you prefer?

    Results (416 votes). Check out past polls.