Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Need to return the first occurance of a search

by mds (Novice)
on Apr 18, 2013 at 14:59 UTC ( [id://1029372]=perlquestion: print w/replies, xml ) Need Help??

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

I need a solution that simulates the rpm -q command as follows:
The linux rpm command returns only the first occurance of what you are looking for.
example:
if you have cups installed
rpm -q cups returns cups-1.5.2-9.fc16.x86_64
and not cups-libs-1.5.2-9.fc16.x86_64
even though cups-libs-1.5.2-9.fc16.x86_64 is installed.

I loaded an array with the output of rpm -qa
I need to do a search on that array (data strucuture is not important to me, it can be anything) using cups as the search string and have it only return cups-1.5.2-9.fc16.x86_64
and not anything else with cups in the string anywhere in the array.
This will effectivly simulate the "rpm -q string" command.
It also must return an empty set indication if only cups-libs-1.5.2-9.fc16.x86_64 exist
but cups-1.5.2-9.fc16.x86_64 does not.
And of course this will work with any string matched against the array. Not just cups.
It's ok if the grep or match or search returns a duplicate.
that is if cups-1.5.2-9.fc16.x86_64 is in the rpm data array twice its ok if it returns it into output of another array.
I have been trying grep and regular expresions, but my regex is not up to solving this particular problem.
Thanks, in advance.

Replies are listed 'Best First'.
Re: Need to return the first occurance of a search
by kennethk (Abbot) on Apr 18, 2013 at 15:19 UTC
    I have been trying grep and regular expresions, but my regex is not up to solving this particular problem.
    What in particular did you try, and what didn't work? Effort demonstrated through posted code is generally taken as a sign of good faith.

    It's fairly simple to test for the existence of a particular string, say cups-1.5.2-9.fc16.x86_64, but what is your intended behavior when the version number changes? My solution might look something like

    perl -e '@arr=`rpm -qa`; if (grep /^cups-\d/, @arr) {print grep /^cups +-\d/, @arr} elsif (grep /^cups-/, @arr) {print "Empty set\n"}'

    Expanding it to handle other leading strings would be easy, though in the general case you may want to escape the string, e.g. /^\Q$name\E-\d/


    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

Re: Need to return the first occurance of a search
by pvaldes (Chaplain) on Apr 18, 2013 at 15:19 UTC

    hum, can't see the point on cloning the red hat package manager

    I'll suggest simply to use system("rpm ...") for this

    And please, note that this is not a "first occurrence's problem", it is a "categorizing packages" problem. You want to print the parent (upper node of the tree) package, not the first package that match the regex

Re: Need to return the first occurance of a search
by hdb (Monsignor) on Apr 18, 2013 at 15:11 UTC

    The distinguishing factor is that a hyphen and a digit follow the name you are looking for.

    use strict; use warnings; my @array1 = qw/ cups-1.5.2-9.fc16.x86_64 cups-libs-1.5.2-9.fc16.x86_6 +4 cups-1.5.2-9.fc16.x86_64/; my @array2 = qw/ cups-libs-1.5.2-9.fc16.x86_64 cups-libs-1.5.2-9.fc16. +x86_64 /; my $pattern = "cups"; print "Array1:\n", join "\n", grep { /^$pattern\-\d/ } @array1; print "\nArray2:\n", join "\n", grep { /^$pattern\-\d/ } @array2;
Re: Need to return the first occurance of a search
by RichardK (Parson) on Apr 18, 2013 at 17:16 UTC

    I don't think I understand what you're after here, but if you need both versions then

    >rpm -q cups cups-1.5.2-9.fc16.x86_64 >rpm -q cups-libs cups-libs-1.5.2-9.fc16.x86_64
      Thank you for your replies. I think I was overthinking the whole thing. First of all I need to explain a few more things. For vaious reasons I can't use the rpm command per package. All I have is an array of the output of rpm -qa. Also, The packages I am checking for have already been split and put into an array. so cups and cups-libs, etc are seperate elements in an array. That piece of information should make this trivial. My apologies for neglecting that. So I think the following works:
      use strict; use warnings; my @search_data = qw( cups cups-libs ); my @rpm_data = qw( cups-1.5.2-9.fc16.x86_64 cups-libs-1.5.2-9.fc16.x86 +_64 ); foreach my $patch_prog ( @search_data ) { my @vers = grep ( /^\Q${patch_prog}\E-\d.*/, @rpm_data ); print "@vers\n"; }
      Which is also what hdb and kennethk offered above. In mine I dont think I need the .* on the end. And I should probably escape the "-". I'm still playing with it. But I think I'm on the right track.
      "but what is your intended behavior when the version number changes?"
      I will be using RPM::vercmp to compare versions. again the version counterpart to the patch_prog part in the search array is also broken out. so I just need to slice and dice from @rpm_data and then do the RPM::vercmp. So the version changing is expected and hopefully will be handled by the RPM module. Which so far, looks like it is doing a pretty good job.

      As far as trying before I posted. For some rason I just could not think of how to write this. I had been looking at so many examples and other solutions I just couldn't see the woods for the trees. Then as soon as I posted the question, The above syntax just dawned on me. *Heavy sigh* Some days are like that. Thank's again for your prompt and professional replies.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1029372]
Approved by NetWallah
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (6)
As of 2024-03-19 02:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found