Link to home
Start Free TrialLog in
Avatar of bb0812
bb0812Flag for United States of America

asked on

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

Avatar of Adam314
Adam314

@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].
Avatar of bb0812

ASKER

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

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

Avatar of bb0812

ASKER

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.  
Avatar of ozo
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
$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
$ARGV[0] = '%eli23*';
$process = $ARGV[0];
$process =~ s/\W+//g;
print $process;
#will print
eli23
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?
$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
Avatar of bb0812

ASKER

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.

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

SOLUTION
Avatar of ozo
ozo
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of bb0812

ASKER

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.
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

Avatar of bb0812

ASKER

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
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.
Avatar of bb0812

ASKER

File has been re-attached.
cmd.txt
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

Avatar of bb0812

ASKER

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'
Do you mean when you type %ELI31*  ?
Where did %ccg* come from?
Avatar of bb0812

ASKER

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))
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?

Avatar of bb0812

ASKER

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

ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of bb0812

ASKER

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 | |

======================================================================
Avatar of bb0812

ASKER

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

Avatar of bb0812

ASKER

Any status on this?  Please help.
Avatar of bb0812

ASKER

Thank you all for your help.  I have figured out how to put the missing header.