• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 179
  • Last Modified:

Need help with grep or matching user input

Hello, I have now received another requirement for the script that I've modified.  I've attached the script, it's working, and now my issue is that when I issue a ./fc.pl %eli31*, they want anything with eli31 to be displayed, and nothing else.  Please help, thanks.
i.e.
./fc.pl %eli31*
Command: fc.pl -s test310:19018 '@fc '

        Client: /ELF310      Node: test310
        ProcName: Eli31Fix0    

         CONNECTIONS
+----------------------+--------------+--------------+-----------+-----------+-+
|   Connection Name    |  API State   |  Fix State   |  Rx Msgs  |  Tx Msgs  | |
+----------------------+--------------+--------------+-----------+-----------+-+
| ELI31PRIMARY           | DisConnected | DisConnected | 000000000 | 000000000 | |
+----------------------+--------------+--------------+-----------+-----------+-+
| ELI31BACKUP          | DisConnected | DisConnected | 000000000 | 000000000 | |
+----------------------+--------------+--------------+-----------+-----------+-+
| ELI31BACKUP2           | DisConnected | DisConnected | 000000000 | 000000000 | |
+----------------------+--------------+--------------+-----------+-----------+-+
| ELI23PRIMARY    | DisConnected | DisConnected | 000000000 | 000000000 | |
+----------------------+--------------+--------------+-----------+-----------+-+
| TEST_PRIMARY     | DisConnected | DisConnected | 000000000 | 000000000 | |
+----------------------+--------------+--------------+-----------+-----------+-+
| TEST_PRIMARY_2     | DisConnected | DisConnected | 000000000 | 000000000 | |

======================================================================
The new way the output should look like:
./fc.pl %eli31*
Command: fc.pl -s test310:19018 '@fc '

        Client: /ELF310      Node: test310
        ProcName: Eli31Fix0    

         CONNECTIONS
+----------------------+--------------+--------------+-----------+-----------+-+
|   Connection Name    |  API State   |  Fix State   |  Rx Msgs  |  Tx Msgs  | |
+----------------------+--------------+--------------+-----------+-----------+-+
| ELI31PRIMARY           | DisConnected | DisConnected | 000000000 | 000000000 | |
+----------------------+--------------+--------------+-----------+-----------+-+
| ELI31BACKUP          | DisConnected | DisConnected | 000000000 | 000000000 | |
+----------------------+--------------+--------------+-----------+-----------+-+
| ELI31BACKUP2           | DisConnected | DisConnected | 000000000 | 000000000 | |
I've written the following code towards the end of the script but it's not working plus it's giving me some errors that I don't understand.  Here's my error:  
Scalar value @ARGV[1] better written as $ARGV[1] at ./cbscmd4fc line 300.
Scalar value @ARGV[1] better written as $ARGV[1] at ./cbscmd4fc line 302.
 
New code was inserted at line 298.
 my $process = "";
 
 for(my $i = 0; $i <= length(@ARGV[1]); $i++) {
       my $char;
       $char = substr(@ARGV[1], $i, 1);
       if($char =~ /\% [A-Za-z] /) {
               $process = $process.$char;
#print "test $process.$char";
       }
}
 
## if($_ =~ /@ARGV[0]/
                       print "$_";
                  ....

Open in new window

0
bb0812
Asked:
bb0812
  • 13
  • 8
  • 7
2 Solutions
 
Adam314Commented:
@ARGV is an array.  $ARGV[1] is the second (first is index 0) element of that array.  @ARGV[1] is an array slice - a part of the array - in this case, an array containing the second element of @ARGV. The warnings are telling you that instead of @ARGV[1], you should be using $ARGV[1].

And since it looks like you want the first argument, not the second, you probably want the 0'th index: $ARGV[0].
0
 
bb0812Author Commented:
I changed the code but I still don't get the output I want.  I do not get the errors anymore, and I changed the value from 1 to 0 to no avail.

my $process = "";
print "@resp";
  for(my $i = 0; $i <= length($ARGV[0]); $i++) {
        my $char;
        $char = substr($ARGV[0], $i, 1);
        if($char =~ /\% [A-Za-z] /) {
                $process = $process.$char;
print "test $process.$char";
 
        }
 }

Open in new window

0
 
Adam314Commented:
I'm not sure what you are trying to do with your code, but if the goal is to remove anything that isn't a percent or a letter, you can use this:
$ARGV[0] =~ s/[^%A-Za-z]//g;

Open in new window

0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
bb0812Author Commented:
The $ARGV variable contains the command @fc %eli23*, I'm trying to get any instance of eli23 and just output that.
Can I use grep instead, if so how.
All I want is to get the output of whatever I type.  For instance, if I have typed, ./fc.pl %test*, I should get test_primary, and test_primary_1.  
0
 
ozoCommented:
all unix command shells will do a file glob expansion of %eli31* before passing the arguments to perl
if you want the script to recieve a literal  '%eli31*' in $ARGV[0] you should quote it
0
 
ozoCommented:
$char = substr($ARGV[0], $i, 1);
        if($char =~ /\% [A-Za-z] /) {
a single character will never match /\% [A-Za-z] / because /\% [A-Za-z] / is 3 characters
0
 
ozoCommented:
$ARGV[0] = '%eli23*';
$process = $ARGV[0];
$process =~ s/\W+//g;
print $process;
#will print
eli23
0
 
Adam314Commented:
What is the rule for taking %eli23* and getting just eli23?  Are you keeping anything that is a letter or number?  Everything except the first and last character?

How are you using eli23?  Are you querying a database using the LIKE operator?  Processing the data in perl using grep?
0
 
ozoCommented:
$ARGV[0] = '%test*';
$process = $ARGV[0];
$process =~ s/%//g;
$process =~ s/\*/.*/g;
# test.* can be used as a regular expression to match test_primary and test_primary_1
0
 
bb0812Author Commented:
I have a main file that is read in by the cmd.pl script.  Here's a snippet of the file:
ETF221                   test221          Tst22Fix         TEST_PRIMARY
ETF221                   test221          Tst22Fix         TEST_PRIMARY_2
ELF310                   test310          Eli31Fix0        ELI31PRIMARY
ELF310                   test310          Eli31Fix0        ELI31BACKUP

I have another script called fc.pl which calls in the cmd.pl script, i.e.
./fc.pl %eli31*

Currently when I execute the script it gives me everything.  All I want is any connection that has eli31 on it, or if I type  ./fc.pl %el*, I want to get any connection that starts with el.  The script should get anything between the % and * or if they just enter a %, get anything afterwards.
./fc.pl %test*
./fc.pl %test_primary  should only about test_primary and not test_primary_2.

0
 
Adam314Commented:
So i'm guessing you are using a regular expression to find the matches.  If so, you need to convert the %eli32* to a regular expression pattern.  It appears that % and * should mean match anything.  If so, use this:


my $pattern = $ARGV[0];    #Get pattern from command line
$pattern =~ s/[%\*]/.*;    #Convert to regular expression pattern
 
#You can now use pattern in a regular expression, eg:
#assuming name contains the name you are searching
if($name =~ /$pattern/i) #name should be included.  The i on the end mean ignore case

Open in new window

0
 
ozoCommented:
# type  ./fc.pl '%el*'
# quoting the * so that the command shell will pass it to the per script
$process = shift;
 $process =~/%//g;
 $process =~/\*/.*/g;
 @ARGV=('mainfile');
 while( <> ){
   print if /\b$process\b/;
}
0
 
bb0812Author Commented:
My server has crashed, and now I have to be rebuilt, once I rebuild I will let you know how testing went with the above solutions.
0
 
Adam314Commented:
Just noticed a typo on my previous post... line 2 should have been
$pattern =~ s/[%\*]/.*/g;    #Convert to regular expression pattern

Open in new window

0
 
bb0812Author Commented:
Besides going on vacation, I finally recovered the server, and now it's working as it's suppose to be.  I tried both solutions to no avail.  I'm pretty sure my question is misleading, so I'll re-write it.

I have a script called fc.pl that calls in the cmd.pl script.  The cmd.pl script goes into an internal program that retrieves the connection information I need once the application is started.  If the application is not up the cmd.pl will state ERROR: TCP Error - Can't connect to..  which works just fine.
Now, the issue is this.  The script works fine but it has a kink on it.  

i.e.  When I execute ./fc.pl %eli31*, I get the following output which gives me everything.  I don't want everything, I just want anything with eli31 on it.  The $proc variable on the script is what gives me the names of connections that I need, that's line 173.

>   ./fc.pl %eli31*
Command: fc.pl -s test310:19018 '@fc '

        Client: /ELF310      Node: test310
        ProcName: Eli31Fix0    

         CONNECTIONS
+----------------------+--------------+--------------+-----------+-----------+-+
|   Connection Name    |  API State   |  Fix State   |  Rx Msgs  |  Tx Msgs  | |
+----------------------+--------------+--------------+-----------+-----------+-+
| ELI31PRIMARY           | DisConnected | DisConnected | 000000000 | 000000000 | |
+----------------------+--------------+--------------+-----------+-----------+-+
| ELI31BACKUP          | DisConnected | DisConnected | 000000000 | 000000000 | |
+----------------------+--------------+--------------+-----------+-----------+-+
| ELI31BACKUP2           | DisConnected | DisConnected | 000000000 | 000000000 | |
+----------------------+--------------+--------------+-----------+-----------+-+
| ELI23PRIMARY    | DisConnected | DisConnected | 000000000 | 000000000 | |
+----------------------+--------------+--------------+-----------+-----------+-+
| TEST_PRIMARY     | DisConnected | DisConnected | 000000000 | 000000000 | |
+----------------------+--------------+--------------+-----------+-----------+-+
| TEST_PRIMARY_2     | DisConnected | DisConnected | 000000000 | 000000000 | |

======================================================================

I only want this:
Command: fc.pl -s test310:19018 '@fc '

        Client: /ELF310      Node: test310
        ProcName: Eli31Fix0    

         CONNECTIONS
+----------------------+--------------+--------------+-----------+-----------+-+
|   Connection Name    |  API State   |  Fix State   |  Rx Msgs  |  Tx Msgs  | |
+----------------------+--------------+--------------+-----------+-----------+-+
| ELI31PRIMARY           | DisConnected | DisConnected | 000000000 | 000000000 | |
+----------------------+--------------+--------------+-----------+-----------+-+
| ELI31BACKUP          | DisConnected | DisConnected | 000000000 | 000000000 | |
+----------------------+--------------+--------------+-----------+-----------+-+
| ELI31BACKUP2           | DisConnected | DisConnected | 000000000 | 000000000 | |
cmd.pl.txt
0
 
Adam314Commented:
I can't access your attachment.  Can you try attaching again, naming it just cmd.txt.  Maybe the .pl.txt is causing a problem with the server.
0
 
bb0812Author Commented:
File has been re-attached.
cmd.txt
0
 
Adam314Commented:
So it looks like the pattern checking is done on line 172.  Is this correct?  If so, try this for debugging

...
foreach my $arg (@inputParams) {
 
    print "**DEBUG: Processing arg '$arg'\n";
    my $rplStr = "";
 
    $cmdKeys[$i] = [];
 
    if ($arg =~ /%(.+)/) {
 
        print "**DEBUG: arg begins with \%: $1\n";
        $rplStr = "$1";
 
        $rplStr =~ s/\?/./g;
 
        $rplStr =~ s/\*/.*/g;
 
        print "**DEBUG: rplStr='$rplStr'\n";
        
 
        print "**DEBUG: Processing everything in \@procList\n";
        foreach  $proc (@procList) {
 
            print "**DEBUG:     Processing proc '$proc'\n";
            if ($proc =~ /^${rplStr}$/i) {
 
                print "**DEBUG:         Matches!\n";
                push (@{$cmdKeys[$i]}, $ctrl{$proc . "_uniqueName"});
 
                print "This is my connection name $proc\n";
 
            }
        
 
        ##)# foreach my $proc (keys(%ctrl)) (
 
        }# for  $proc (keys(%ctrl)) {
        my $cnt = @{$cmdKeys[$i]};
        if (! $cnt) {
            print "No Matching Process\n";
            @cmdKeys = [];
        }
    } else {
        push (@{$cmdKeys[$i]}, $arg." ".$proc);
    }# if
    
    ++$i;
}# foreach my $arg (@inputParams)
...

Open in new window

0
 
bb0812Author Commented:
Adam314,
The debug statements worked, but my issue is that when I type ELI31 all I want is the connections that start with ELI31, and I want it to ignore everything else.

**DEBUG:  Processing arg '@fc'
**DEBUG:  Processing arg '%ccg*'
**DEBUG:  arg begins with %: ccg*
**DEBUG:  rplStr='ccg.*'
**DEBUG:  Processing everything in @procList
**DEBUG:  Processing proc 'PROCESS'
**DEBUG:  Processing proc '---------------'
**DEBUG:  Processing proc 'TEST_SYSTEM'
**DEBUG:  Processing proc 'TEST_SYSTEM2'
**DEBUG:  Processing proc 'ELI31PRIMARY'
**DEBUG:  Matches!
This is my connection name ELI31PRIMARY
**DEBUG:  Processing proc 'ELI31BACKUP'
**DEBUG:  Matches!
This is my connection name ELI31BACKUP
**DEBUG:  Processing proc 'ELI31BACKUP2'
**DEBUG:  Matches!
This is my connection name ELI31BACKUP2
**DEBUG:  Processing proc 'TEST_PRIMARY'
**DEBUG:  Processing proc 'TEST_PRIMARY_2'
0
 
ozoCommented:
Do you mean when you type %ELI31*  ?
Where did %ccg* come from?
0
 
bb0812Author Commented:
I cut and pasted pieces of the wrong screen.  Yes, everything has to be %ELI31*
On another note, I found that the $kw variable holds %eli31*,  and the @resp holds the entire output, which includes TEST_SYSTEM, TEST_PRIMARY, etc...  How do I match $kw to just print out anything with eli31, note:  I don't need the % nor the *.  Can I accomplish this with a match of $kw?

        if (($exitFlag == 0) && (@inputParams > 0)) {
                my $kw = $inputParams[1];
                $kw =~ tr/a-z/A-Z/;
                if (($kw eq "QUIT") || ($kw eq "EXIT")) {
                        $exitFlag = -1;
                } else {
                        my @resp = &processInputParams;
print "*******DEBUG:  what is kw KW KW KW $kw\n";
                        foreach (@resp) {
                                print "$_";
                        }
                }
        }#if (($exitFlag == 0) && (@inputParams > 0))
0
 
ozoCommented:
WHat iwas the debug output when @resp holds the entire output?
It should not be possible to have
**DEBUG:  rplStr='ELI31.*'
**DEBUG:  Processing everything in @procList
**DEBUG:  Processing proc 'TEST_SYSTEM'
**DEBUG:  Matches!

 but if there is another element in @inputParams that is not %ELI31*, then that would create a different @{$cmdKeys[$i]}  list
so could the extra lines have come from a different arg?

0
 
bb0812Author Commented:
Here's a code snippet of where I think my issue lies.  The $kw variable looks for the $inputParams entry which I have it as [1] which contains %eli31*.   [0] just has FC.  The @resp issues the output of the sub processInputParams.

Here's the output:
*******DEBUG:  what is KW %ELI31*
===========DEBUG======  This is my resp @resp
Command:fc.pl -s test310:19018 '@fc '

===========DEBUG======  This is my resp @resp

===========DEBUG======  This is my resp @resp

===========DEBUG======  This is my resp @resp

===========DEBUG======  This is my resp @resp
        Client: /ELF310      Node: test310
===========DEBUG======  This is my resp @resp
        ProcName: Eli31Fix0    
===========DEBUG======  This is my resp @resp

===========DEBUG======  This is my resp @resp

===========DEBUG======  This is my resp @resp

===========DEBUG======  This is my resp @resp
                    CONNECTIONS
===========DEBUG======  This is my resp @resp
+----------------------+--------------+--------------+-----------+-----------+--
------------+--------------+
===========DEBUG======  This is my resp @resp
|   Connection Name    |  API State   |  Fix State   |  Rx Msgs  |  Tx Msgs  |
x Sequence  | Tx Sequence  |
===========DEBUG======  This is my resp @resp
+----------------------+--------------+--------------+-----------+-----------+-
------------+--------------+
===========DEBUG======  This is my resp @resp
| ELI31PRIMARY            | Connected    | Connected    | 000000659 | 000000656 |
00000000659 | 000000000000 |
===========DEBUG======  This is my resp @resp
+----------------------+--------------+--------------+-----------+-----------+-
------------+--------------+
===========DEBUG======  This is my resp @resp
| ELI31BACKUP         | Connected    | Connected    | 000000660 | 000000656 |
00000000660 | 000000000000 |
===========DEBUG======  This is my resp @resp
+----------------------+--------------+--------------+-----------+-----------+-
------------+--------------+
===========DEBUG======  This is my resp @resp
| ELI31BACKUP2           | Connected    | Connected    | 000000660 | 000000656 |
00000000660 | 000000000000 |
===========DEBUG======  This is my resp @resp
+----------------------+--------------+--------------+-----------+-----------+--
------------+--------------+
===========DEBUG======  This is my resp @resp
| TEST_PRIMARY          | Connected    | Connected    | 000000660 | 000000656 | 0
00000000660 | 000000000000 |
===========DEBUG======  This is my resp @resp
+----------------------+--------------+--------------+-----------+-----------+--
------------+--------------+
===========DEBUG======  This is my resp @resp
| TEST_PRIMARY_2          | Connected    | DisConnected | 000000000 | 000000000 | 0
00000000000 | 000000000000 |
===========DEBUG======  This is my resp @resp

#
# User Command Interface
#
my $exitFlag = 0;
$argCnt = @ARGV;
while ($exitFlag == 0) {
        my $cmd = "";
        if (! $argCnt) {
                print "cbscmd > ";
                if (eof(STDIN)) {
                        $exitFlag = -1;
                } else {
                        $cmd = <STDIN>;
                        chomp ($cmd);
                        $cmd =~ s/\s+/ /g;
                        $cmd =~ s/^\s//g;
                        @inputParams = split(/ /,$cmd);
                }# if (length($cmd)) {
        } else {
                @inputParams = @ARGV;
        }# if (! $argCnt) {
 
        if (($exitFlag == 0) && (@inputParams > 0)) {
                my $kw = $inputParams[1];
                $kw =~ tr/a-z/A-Z/;
                if (($kw eq "QUIT") || ($kw eq "EXIT")) {
                        $exitFlag = -1;
                } else {
                        my @resp = &processInputParams;
print "*******DEBUG:  what is KW $kw\n";
                        foreach (@resp) {
print "===========DEBUG======  This is my resp \@resp\n";
                                print "$_";
                        }
                }
        }#if (($exitFlag == 0) && (@inputParams > 0))
 
        if ($argCnt) {
                $exitFlag = -1;
        }
}# while ($exitFlag = 0) {

Open in new window

0
 
Adam314Commented:

#
# User Command Interface
#
my $exitFlag = 0;
$argCnt = @ARGV;
while ($exitFlag == 0) {
        my $cmd = "";
        if (! $argCnt) {
                print "cbscmd > ";
                if (eof(STDIN)) {
                        $exitFlag = -1;
                } else {
                        $cmd = <STDIN>;
                        chomp ($cmd);
                        $cmd =~ s/\s+/ /g;
                        $cmd =~ s/^\s//g;
                        @inputParams = split(/ /,$cmd);
                }# if (length($cmd)) {
        } else {
                @inputParams = @ARGV;
        }# if (! $argCnt) {
 
        if (($exitFlag == 0) && (@inputParams > 0)) {
                my $kw = $inputParams[1];
                $kw =~ tr/a-z/A-Z/;
                my $re = $kw;
                $re =~ s/%//g;
                $re =~ s/\*/.*/;
                if (($kw eq "QUIT") || ($kw eq "EXIT")) {
                        $exitFlag = -1;
                } else {
                        my @resp = &processInputParams;
                        next unless "@resp" =~ /$re/;
print "*******DEBUG:  what is KW $kw\n";
                        foreach (@resp) {
print "===========DEBUG======  This is my resp \@resp\n";
                                print "$_";
                        }
                }
        }#if (($exitFlag == 0) && (@inputParams > 0))
 
        if ($argCnt) {
                $exitFlag = -1;
        }
}# while ($exitFlag = 0) {

Open in new window

0
 
bb0812Author Commented:
Adam,
Below is the output, I'm still getting the entire output.

*******DEBUG:  what is KW %ELI31* what is RE ELI31
Command:fc.pl -s test310:19018 '@fc '
        Client: /ELF310      Node: test310
        ProcName: Eli31Fix0    

         CONNECTIONS
+----------------------+--------------+--------------+-----------+-----------+-+
|   Connection Name    |  API State   |  Fix State   |  Rx Msgs  |  Tx Msgs  | |
+----------------------+--------------+--------------+-----------+-----------+-+
| ELI31PRIMARY           | DisConnected | DisConnected | 000000000 | 000000000 | |
+----------------------+--------------+--------------+-----------+-----------+-+
| ELI31BACKUP          | DisConnected | DisConnected | 000000000 | 000000000 | |
+----------------------+--------------+--------------+-----------+-----------+-+
| ELI31BACKUP2           | DisConnected | DisConnected | 000000000 | 000000000 | |
+----------------------+--------------+--------------+-----------+-----------+-+
| ELI23PRIMARY    | DisConnected | DisConnected | 000000000 | 000000000 | |
+----------------------+--------------+--------------+-----------+-----------+-+
| TEST_PRIMARY     | DisConnected | DisConnected | 000000000 | 000000000 | |
+----------------------+--------------+--------------+-----------+-----------+-+
| TEST_PRIMARY_2     | DisConnected | DisConnected | 000000000 | 000000000 | |

======================================================================
0
 
bb0812Author Commented:
Adam314, I made a change to your suggestion, and I have it working, but I lost my header.  Is there a way I can keep my header.  Attached is the code snippet.  I commented out the next statement and I added the if after the foreach line.  My output now looks like this.

| ELI31PRIMARY           | DisConnected | DisConnected | 000000000 | 000000000 | |
| ELI31BACKUP          | DisConnected | DisConnected | 000000000 | 000000000 | |
| ELI31BACKUP2           | DisConnected | DisConnected | 000000000 | 000000000 | |

I'm missing the following:
Command:fc.pl -s test310:19018 '@fc '
        Client: /ELF310      Node: test310
        ProcName: Eli31Fix0    

         CONNECTIONS
+----------------------+--------------+--------------+-----------+-----------+-+
|   Connection Name    |  API State   |  Fix State   |  Rx Msgs  |  Tx Msgs  | |
+----------------------+--------------+--------------+-----------+-----------+-+

How can I get the header above.


                        my @resp = &processInputParams;
                        ## next unless "@resp" =~ /$re/;
## print "*******DEBUG:  what is KW: $kw what is RE: $re \n";
                        foreach (@resp) {
                if ($_ =~ /$re/) {
##  print "===========DEBUG======  This is my resp \@resp\n";
                                print "$_";
                                 }
 
                        }

Open in new window

0
 
bb0812Author Commented:
Any status on this?  Please help.
0
 
bb0812Author Commented:
Thank you all for your help.  I have figured out how to put the missing header.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 13
  • 8
  • 7
Tackle projects and never again get stuck behind a technical roadblock.
Join Now