简体   繁体   中英

perl - redirect system command to a file

I have this perl code below, basically want to loop through these 2 files. Then call a bash script (it takes the file and a delimiter as arguments and it prints out multiple lines) and then save all output from that command into a new file (with filename having '_processed' tacked on the end). What is wrong with the below syntax (at the moment it just creates a blank file)?

#!/usr/bin/env perl
use strict;
use warnings;

my(@files) = (
"fixedtt.txt '|'",
"delimd2iffpipe.dat '|'"
);
for my $i (0 .. $#files) {
    my($filename) = split /[\s]+/, "$files[$i]", 2;
    my($name, $type) = split /[\.]+/, "$filename", 2;
    open (MYFILE, '>'."$name".'_processed.'."$type");
    system("sh myBashScript.sh $files[$i]");   #I want to write the entire output of this command to a file
    close (MYFILE); 
}

You can redirect the output of a terminal command by preceding it with > <file name> . Ergo:

system("sh myBashScript.sh $files[$i]");

Becomes:

system("sh myBashScript.sh $files[$i] > file.txt");

You seem to be confused with how perl writes to files. Your open and close on the MYFILE handle will only create an empty file. system does not do anything to that file within perl. (Though I cannot say what your sh-script does with it).

Some pointers:

  • You are using the indexes of @files instead of the elements, which reduces readability for no reason, since the indexes themselves are not used anywhere.
  • You are using split to extract file name and extension, and I assume there's a reason for that. However, there's no need to set LIMIT to 2, since you are only ever using the first one or two elements from that split.
  • When you only have one character (or character class, eg \\s ), the brackets are not needed. So, use \\s instead of [\\s] .
  • It is recommended to use the three-argument open with a lexical file handle.
  • Capturing output (to stdout) is done with backticks or qx() . system only returns the return value of the system call. dunsmoreb is correct that you can simply redirect in the shell to create the file, but this is how it's done inside perl.

If I were to guess, I'd say you were trying to write the output of the bash script to the file you are attempting to open, in which case you should do:

my @files = (
    "fixedtt.txt '|'",
    "delimd2iffpipe.dat '|'"
);
for my $args (@files) {
    my ($filename)    = split ' ', $args;
    $filename =~ s/\./_processed./;
    open my $fh, '>', $filename or die $!;
    print $fh qx(sh myBashScript.sh $args);
    close $fh; 
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM