error in system command to output - perl

I want to run ext software (hmmer) commands through perl in a loop for input files (in linux).
I used this line
system "hmmbuild $outfile $files";
where $outfile is my output file and $files in my input files. hmmbuild is the command for the ext software.
When I run the program it gives me error code for the output file GLOB(0x1b94b220).
Can any one help me where I am wrong and how can it be corrected?
I tried exec command also with back tick and brackets.
This is the exact output message i got. How can I print my result to output file ($outfile)?
sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `hmmbuild --amino GLOB(0x11eb3220) aproNOG00001'
script goes here..
#!/usr/bin/perl
use Bio::AlignIO;
use Bio::Align::AlignI;
my $allfiles= 'allfilenames_alpha_hmms.txt';
system "module load hmmer/3.1b1";
print "loaded hmmer\n";
open(FIH, $allfiles);
while ($min=<FIH>)
{ chomp($min); my #pats=split " ",$min;
foreach my $files(#pats) {
print $files; print "\n";
open(my $outfile, '>',"$prefix.hmm");
system "hmmbuild --amino $outfile $files";
print $outfile;
print "file saved\n";
# }
}
}
print "\n\n\n\t ###\tDONE\t### \n\n";

how can i print my result to output file ($outfile)
I take it hmmbuild expects a path to a file? Pass the path to the file rather than what's in $outfile.
system "hmmbuild --amino $prefix.hmm $files";

Related

How to read the textfile by command line arguments and print the column by using perl?

How to read the text file using perl command line arguments and print the third column using perl?
I'm struck with taking input from the command line and printing the required column. Help me to choose the right way to reach the expected output.
Code which I wrote to take command line input:(map.pl)
use strict;
use warnings 'all';
use Getopt::Long 'GetOptions';
my #files=GetOptions(
'p_file=s' => \my $p_file,
);
print $p_file ? "p_file = $p_file\n" : "p_file\n";
Output I got for above code:
perl map.pl -p_file cat.txt
p_file = cat.txt
cat.txt:(Input file)
ADG:YUF:TGH
UIY:POG:YTH
GHJUR:"HJKL:GHKIO
Expected output:
TGH
YTH
GHKIO
Perl can automatically read files whose names are provided as command line arguments. The command below should produce your expected output
perl -F: -le 'print $F[2]' cat.txt
-F: turns on autosplit mode, sets the field separator to : and loops over lines of input files. -l handles line endings during input and output. The code after e flag ('print $F[2]' prints 3rd field) is executed for each line of file. Find out more by reading perldoc perlrun.
You'd need to read the file and split the lines to get the columns, and print the required column. Here's a demo code snippet, using the perl -s switch to parse command line arguments. Run like this ./map.pl -p_file=cat.txt
#!/usr/bin/perl -s
use strict;
use warnings;
use vars qw[$p_file];
die("You need to pass a filename as argument") unless(defined($p_file));
die("Filename ($p_file) does not exists") unless(-f $p_file);
print "Proceeding to read file : $p_file\n\n";
open(my $fh,'<',$p_file) or die($!);
while(chomp(my $line = <$fh>)) {
next unless(defined($line) && $line);
my #cols = split(/:/,$line);
print $cols[-1],"\n";
}
close($fh);

perl breaks file path into new lines

Instead of printing the file into one line, the output is a bunch of new lines. What am I ding wrong in the file path of this perl script?
Script:
my $app = $ARGV[0];
my $day=`date -v-1d '+%d'`;
my $month=`date -v-1d '+%b'`;
my $yr=`date -v-1d '+%Y'`;
my $file = "/path/to/file/$app/$yr/$month/treshold-$day .log";
print $file;
Result:
$ perl test.pl inter
/path/to/file/inter/2013
/Dec
/treshold-13
Output should be: /path/to/file/inter/2013/Dec/treshold-13.log
date(1) write an end-of-line at the end of the output. Use chomp to throw it away.

How to calculate size of a file from the command line arguments in perl

I was trying out a sample program that can calculate the size of the file given in command line arguments. It gives the size correctly when I have a file name stored inside a variable, but doesn't output a result when got the filename from the command line arguments.
#! /usr/bin/perl
use File::stat;
while(<>){
if(($_ cmp "\n") == 0){
exit 0;
}
else{
my $file_size = stat($_)->size; # $filesize = s $_;
print $file_size;
}
}
I get no output when using file test operator -s and I get errors when using stat module:
Unsuccessful stat on filename containing newline at /usr/share/perl/5.10/File/stat.pm line 49, <> line 1.
Can't call method "size" on an undefined value at 2.pl line 17, <> line 1.
1.txt is the filename I'm giving as an input.
#!/usr/bin/perl
for (#ARGV){
my $file_size = -s $_;
print $file_size;
}
or similar cmd oneliner,
perl -E 'say "$_, size: ", -s for #ARGV' *
#!/usr/bin/perl -w
$filename = '/path/to/your/file.doc';
$filesize = -s $filename;
print $filesize;
Simple enough, right? First you create a string that contains the path to the file that you want to test, then you use the -s File Test Operator on it. You could easily shorten this to one line using simply:
print -s '/path/to/your/file.doc';
Also, keep in mind that this will always return true if a file is larger than zero bytes, but will be false if the file size is zero. It makes a handy and quick way to check for zero byte files.

Perl: How to "die" with no error message?

I run a simple file test in perl with the code below:
my $f1 = "$pre_file";
unless (-e $1) {
print "\n Pre_check file does not exists! \n";
die;
}
It prints the following output:
Pre_check file does not exists!
Died at ./huawei-postcheck line 81.
However I do not want the last line "Died at ./huawei-postcheck line 81.".
I want to to "die" with no error message.
Is it possible?
See the documentation for die.
If the last element of LIST does not end in a newline, the current
script line number and input line number (if any) are also printed,
and a newline is supplied.
So you can get die to work without printing anything by just using die "\n". But given that you have an error message, I can't see why you don't use that.
unless (-e $f1) {
die "\n Pre_check file does not exist!\n";
}
Of course, the difference is that the message will now go to STDERR rather than STDOUT. But that's probably the right place for it to go.
use exit instead of die.
You could just say
die "\n";
to suppress the message.
You probably want to exit 1 instead of dying then.
my $f1 = "$pre_file";
unless (-e $1) {
print "\n Pre_check file does not exists! \n";
exit 1;
}

Cannot find argument passed to program called using Perl "system" command

I'm writing a Perl script to run an external program on every file in a directory. This program converts files from one format to another. Here's the deal...
When I run the program from the command line, everything works as it should:
computer.name % /path/program /inpath/input.in /outpath/output.out
converting: /inpath/input.in to /outpath/output.out
computer.name %
Here's the code I wrote to convert all files in a directory (listed in "file_list.txt"):
#!/usr/bin/perl -w
use warnings;
use diagnostics;
use FileHandle;
use File::Copy;
# Set simulation parameters and directories
#test_dates = ("20110414");
$listfile = "file_list.txt";
$execname = "/path/program";
foreach $date (#test_dates)
{
# Set/make directories
$obs_file_dir = "inpath";
$pred_file_dir = "outpath";
mkdir "$pred_file_dir", 0755 unless -d "$pred_file_dir";
# Read input file names to array
$obs_file_list = $obs_file_dir . $listfile;
open(DIR, $obs_file_list) or die "Could not open file!";
#obs_files = <DIR>;
close(DIR);
# Convert and save files
foreach $file (#obs_files)
{
$file =~ s/(\*)//g;
$infile = $obs_file_dir . $file;
$outfile = $pred_file_dir . $file;
$outfile =~ s/in/out/g;
print $infile . "\n";
#arg_list = ($execname, $infile, $outfile);
system(#arg_list);
}
}
The output shows me the following error for every file in the list:
computer.name % perl_script_name.pl
/inpath/input.in
converting: /inpath/input.in to /outpath/output.out
unable to find /inpath/input.in
stat status=-1
error while processing the product
I verified every file is in the proper place and have no idea why I am getting this error. Why can't the files be found? When I manually pass the arguments using the command line, no problem. When I pass the arguments through a variable via a system call, they can't be found even though the path and file names are correct.
Your advice is greatly appreciated!
Your list of files (#obs_files) comes from reading in a file via #obs_files = <DIR>;
When you do that, each element of array will be a line from a file (e.g. directory listing), with the line being terminated by a newline character.
Before using it, you need to remove the newline character via chomp($file).
Please note that s/(\*)//g; does NOT remove that trailing newline!