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

I am haing a hard time getting this subroutine to work properly. The issue I am having is that the output skips all the way to the last else statement and prints "This is not a file! Attempting to process BTN...". Apparently I am missing something in my pattern matching, but I cannot figure it out. Any help would be much appreciated.

use strict; use warnings; use Getopts::Std; #Global Variables my $in_file = $ARGV[0]; my $encoding = ":encoding(UTF-8)"; #Check file to see what type of file you are looking at. sub check_file { my $head = system head => -1 => $in_file; # Grab header/first line + of file print $head; if ( $head =~ m/^ABC/ ) { print "This is a ABC File. Processing ABC File...\n"; prcss_abc_file(); } else { if ( $head =~ m/^ISA~ / ) { print "This is an EDI File. Processing EDI File...\n"; prcss_edi_file(); } else { print "This is not a file! Attempting to process BTN.. +.\n"; prcss_btn(); } } } check_file();

Replies are listed 'Best First'.
Re: Matching patterns in condisional statements
by haukex (Archbishop) on Jul 05, 2017 at 16:16 UTC
    my $head = system head => -1 => $in_file; # Grab header/first line of file

    system does not return the output of the command, it returns its exit code. There are ways to get the output in Perl*, but I would instead recommend opening and reading the file using the tools built into Perl (see e.g. Files and I/O):

    use warnings; use strict; my $ENCODING = ":encoding(UTF-8)"; die "Usage: $0 FILENAME\n" unless @ARGV==1; check_file($ARGV[0]); sub check_file { my ($in_file) = @_; open my $fh, "<$ENCODING", $in_file or die "Failed to open $in_file: $!\n"; my $head = <$fh>; close $fh; if ( $head =~ m/^ABC/ ) { print "This is a ABC File. Processing ABC File...\n"; prcss_abc_file($in_file); } elsif ( $head =~ m/^ISA~ / ) { print "This is an EDI File. Processing EDI File...\n"; prcss_edi_file($in_file); } else { print "I don't know this file type! Attempting to process BTN. +..\n"; prcss_btn($in_file); } }

    (* For example backticks, but as I wrote about at length here, I wouldn't recommend it for this task. If you really wanted to capture the output, at least use capturex from IPC::System::Simple.)

    Update: Note that I am just guessing as to the purpose of the $encoding variable in the code you showed.

Re: Matching patterns in condisional statements
by Eily (Monsignor) on Jul 05, 2017 at 16:14 UTC

    What does print $head print? Rather than just print the string I'd use Data::Dump or Data::Dumper (with $Data::Dumper::Useqq set to true) to display it, to see potential invisible characters

      It was so I could see that the first line was being stored in the $head variable.

Re: Matching patterns in condisional statements
by 1nickt (Canon) on Jul 05, 2017 at 16:13 UTC

    Hi, think about it: how should someone assist you without some samples of what should match for each type of file? Please provide some sample data.

    Also, you should use Perl to read the file, not shell out to a separate program executable.

    Also, when you print $head, does it contain what you expect?


    The way forward always starts with a minimal test.
      I cannot see why you would need a data sample since all I am doing is matching a string pattern with the file Header, so I can identify the file type. The string I am looking for can be found in the code. In the future I will use Perl, rather than shell to read the file. thank you. Originally, I thought that $head was storing the first line/header that I expected since it was printing to the screen, but it was actually storing in stdout. An issue that has been addressed and fixed my issue. Thank you for your input.
        I cannot see why you would need a data sample

        Because it allows for a completely reproduceable situation where someone wanting to help only has to copy/paste and not try to recreate input data by hand (and possibly get it wrong).

        Please see Short self-contained correct example.