Solved

How to correct Perl Input file error?

Posted on 2013-12-10
20
604 Views
Last Modified: 2013-12-15
After running the following command:
perl splitfiles.pl -i SSTEST*.txt -c test.conf -e error.txt -r report.txt
I get the following error at 1ine 132:
Unable to open SSTEST*.txt at splitfiles.pl line 132.

Below are lines 130, 131, 132 and Configuration Section
line 130      # open files
line 131     my $input_fh;  # *test+1 9/11 206168
line 132    open($input_fh, "<", $INPUT_FILE) or die "Unable to open $INPUT_FILE";
File pattern which needs to split are SSTEST.5 digits.9 digits.YYYYMMDD.835

# Configuration Section
# The users can define defaults that they want to use
$INPUT_FILE  = "test.txt";
$ERR_OUTFILE = "error.txt";
$CONFIG_FILE = "remit.conf";
$ORPHAN_FILE = "orphan.txt";

Also I need to run this from crontab.
0
Comment
Question by:jamar49
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 7
  • 2
  • +2
20 Comments
 
LVL 37

Expert Comment

by:TommySzalapski
ID: 39710429
"File pattern which needs to split are SSTEST.5 digits.9 digits.YYYYMMDD.835"
No .txt? Your pattern is SSTEST*.txt but the example you gave has no .txt
Do you just want SSTEST*? Is there anything else that starts SSTEST that you don't want to split?
0
 

Author Comment

by:jamar49
ID: 39710449
File pattern which needs to split are SSTEST.5 digits.9 digits.YYYYMMDD.835 with that being said should convert .835 to .txt then run perl script
0
 

Author Comment

by:jamar49
ID: 39710500
There isn't anything else that starts SSTEST that I don't want to split
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 84

Expert Comment

by:ozo
ID: 39710506
Is there any other place where $INPUT_FILE  is set?
$INPUT_FILE  = "test.txt";
 open($input_fh, "<", $INPUT_FILE) or die "Unable to open $INPUT_FILE";
would not produce the message
Unable to open SSTEST*.txt at splitfiles.pl line 132.
0
 
LVL 48

Assisted Solution

by:Tintin
Tintin earned 125 total points
ID: 39710550
Change

open($input_fh, "<", $INPUT_FILE) or die "Unable to open $INPUT_FILE";

to

open($input_fh, "<", $INPUT_FILE) or die "Unable to open $INPUT_FILE because $!\n";

I suspect you have a permission issue.
0
 

Author Comment

by:jamar49
ID: 39710564
permission is 775
Hereare other places where $INPUT_FILE  is set:

# Configuration Section
# The users can define defaults that they want to use
$INPUT_FILE  = "test.txt";

sub usage {
    print "Usage: $0 [-c configuration file] [-i <Input file>] [-e <error file>] [-r <reporting file>] [-s 0] [-f 1] [-o <orphaned claims>] [-d <detailed report>] [-rc <report by check>] [-p <split by payor>] [-n 1] [-sc <allow check type switch>] \n";    #*BJK 1/10 167916
    exit(1);
}

if (@ARGV>0) {     # process command-line arguments
    my $i;

    if ((@ARGV % 2) != 0) { usage()};  # error out if the number of arguments is odd
   
    for ($i=0; ($i<@ARGV+0);) {
        if ($ARGV[$i] eq "-c") {
            $i++;
            $CONFIG_FILE = $ARGV[$i++];
        } elsif ($ARGV[$i] eq "-i") {
            $i++;
            $INPUT_FILE = $ARGV[$i++];


# read the config file and return the number of lines
sub readconfig {
    my $confFile  = shift();
    my $line      = 0;
    my $index     = 0;
    my @timelist  = localtime;
    my $Time      = sprintf("%02d", ($timelist[4]+1)).sprintf("%02d", $timelist[3]).sprintf("%02d", ($timelist[5]-100)).sprintf("%02d", $timelist[2]).sprintf("%02d", $timelist[1]);
    my $TimeWSec      = sprintf("%02d", ($timelist[4]+1)).sprintf("%02d", $timelist[3]).sprintf("%02d", ($timelist[5]-100)).sprintf("%02d", $timelist[2]).sprintf("%02d", $timelist[1]).sprintf("%02d",$timelist[0]);
    my $ExtTime   = sprintf("%04d", ($timelist[5]+1900)).sprintf("%02d", ($timelist[4]+1)).sprintf("%02d", $timelist[3]).sprintf("%02d", $timelist[2]).sprintf("%02d", $timelist[1]).sprintf("%02d", $timelist[0]);
   
    my $conf_fh;  # *test+1 9/11 206168
    open($conf_fh, "<","$confFile") or die("readconfig: unable to open $confFile");
    my @elms = split("/", $INPUT_FILE);
    my $input_file = $elms[$#elms];
0
 
LVL 84

Expert Comment

by:ozo
ID: 39710568
Most unix shells would expand SSTEST*.txt on the command line to a list of  file names matching that pattern, unless no matching file names are found.

And if more than one matching file names are found, it does not appear that the  for ($i=0; ($i<@ARGV+0);) { loop would process them sensibly, though it is hard to be sure, since it also seems to have missing close }
0
 

Author Comment

by:jamar49
ID: 39710592
Ozo I understand that and  I should have said in the being that script will work as long as I use the following :

perl splitfiles.pl -i SSTEST.5 digits.9 digits.YYYYMMDD.835 -c test.conf -e error.txt -r report.txt

But I was trying to use a wildcard because there will be multiple files and each file will have a different "5 digits.9 digits.YYYYMMDD" and I want automate script to run in cron.
0
 
LVL 84

Expert Comment

by:ozo
ID: 39710598
I see where the for loop would set $INPUT_FILE to "SSTEST.5" but I don't see what would be done with digits.9 digits.YYYYMMDD.835

What would different "5 digits.9 digits.YYYYMMDD" look like?
0
 

Author Comment

by:jamar49
ID: 39710604
file pattern  "SSTEST.5 digits.9 digits.YYYYMMDD.835"  examples are
SSTEST.12345.123456789.20131210.835 or SSTEST.12345.12345m789.20131210.835 or
 SSTEST.12345.000056789.20131210.835 and so fore.

The actual command would look like this:
perl splitfiles.pl -i SSTEST.12345.000056789.20131210.835 -c test.conf -e error.txt -r report.txt
0
 
LVL 84

Expert Comment

by:ozo
ID: 39710612
You might use
perl splitfiles.pl -i SSTEST.[0-9][0-9][0-9][0-9][0-9].[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].835 -c test.conf -e error.txt -r report.txt
Assuming there was one and only one file name matching that pattern.
Or, if you know you will always invoke the program with the same pattern, and you are able to modify the perl source code, you might build it in as a default parameter, and then you could also decide on the appropriate action in the case when more than one file name matches.
0
 

Author Comment

by:jamar49
ID: 39710619
There will never be more than one file the exact same name
After running  perl splitfiles.pl -i SSTEST.[0-9][0-9][0-9][0-9][0-9].[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].835 -c test.conf -e error.txt -r report.txt

This is the error I get:
file] [-i <Input file>] [-e <error file>]                                  <
sh: Input: Cannot find or open the file.
$ o <orphaned claims>] [-d <detailed report>                                 <
sh: Syntax error: `newline or ;' is not expected.
$ y payor>] [-n 1] [-sc <allow check type sw                                 <
sh: report: Cannot find or open the file.
$ itch>]
0
 
LVL 84

Expert Comment

by:ozo
ID: 39710621
The error you get seems to wrap at strange places, and also looks a lot like sh was trying to run the Usage message as a command.
Did you perchance try to put the perl command line inside of `` or $()?

And was there one and only one file name matching the pattern?
0
 

Author Comment

by:jamar49
ID: 39711166
Did you perchance try to put the perl command line inside of `` or $()? No

And was there one and only one file name matching the pattern? No
0
 
LVL 37

Assisted Solution

by:TommySzalapski
TommySzalapski earned 125 total points
ID: 39711449
The reason it didn't find anything with the wildcard was because the wildcard was looking for *.txt and the files don't have a .txt

If you take your original script and just remove the .txt after the * it should find the files.
0
 
LVL 84

Assisted Solution

by:ozo
ozo earned 125 total points
ID: 39712539
The posted code only appears to parse one argument after the -i, so if more than one filename matches the pattern, it is not likely to work.
You would need to either use a pattern that matches exactly one file on the command line,
or modify the code to do something sensible when there are more than one file names after the -i or no file names after the -i.
You would also have to decide what that sensible action should be.
0
 

Author Comment

by:jamar49
ID: 39713885
Give me an example of modify the code to do something sensible when there are more than one file names after the -i  that matches the pattern or no file names after the -i.
0
 
LVL 84

Expert Comment

by:ozo
ID: 39713894
Give me an example of a sensible thing to do.

I would have thought that generating an error would be a sensible response to erroneous input.
0
 

Author Comment

by:jamar49
ID: 39715198
New at perl but I need my code to work when more one filename matches the file pattern.
0
 
LVL 12

Accepted Solution

by:
stefan73 earned 125 total points
ID: 39715463
Wrap it in a shell loop:
for file in SSTEST*.txt; do perl splitfiles.pl -i $file -c test.conf -e error.txt -r report.txt; done

Or you can do the globbing in the Perl code; in this case, you need to quote the "SSTEST*.txt" argument in the shell:
@files = glob $filepattern;
for my $file (@files) { ... }
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Every server (virtual or physical) needs a console: and the console can be provided through hardware directly connected, software for remote connections, local connections, through a KVM, etc. This document explains the different types of consol…
This is about my first experience with programming Arduino.
With the power of JIRA, there's an unlimited number of ways you can customize it, use it and benefit from it. With that in mind, there's bound to be things that I wasn't able to cover in this course. With this summary we'll look at some places to go…

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question