LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 10-25-2005, 03:56 AM   #1
apeekaboo
Member
 
Registered: Apr 2003
Location: Stockholm/Sweden
Distribution: Kubuntu, Debian, Slax
Posts: 91

Rep: Reputation: 16
perl: easiest way to extract scalars from lists?


I'd like to pull out some stuff from a list to a scalar, and I'm wondering what the easiest way is to accomplish this.
In this example I'm using LDAP, but that's not really relevant to the question...
Code:
@search = `ldapsearch -x -LLL -D "uid=admin,o=example.org" -w secret -h server -b o=example.org -x "(&(objectclass=posixgroup)(cn=*)(gidnumber=2420)(memberuid=papi))"`;

# GIVES OUTPUT LIKE THIS:
# dn: cn=wittgenstein,ou=Group,ou=Services,o=example.org
#  objectclass: top
#  objectclass: posixgroup
#  gidnumber: 2420
#  cn: wittgenstein
#  description: all users at example.org
#  memberuid: lolj
#  memberuid: papi
#  memberuid: anwa
#  memberuid: kewa
#  memberuid: pewa
#  memberuid: pio
#  memberuid: administrator
#  memberuid: pefi


# TODO: could this be simplified...? i.e. done in fewer steps?
# ideally the list would be left untouched.
@groupname = grep {$_ =~ s,^cn: ,,g } @search;  # extract common name, remove attribute
$groupname = shift @groupname;
chomp $groupname;
print "$groupname\n@search"
I'm not even sure grep is the best way to do this. Perhaps there is a better way?
I'm hoping for a one-liner here... like $groupname = chomp(grep {$_ =~ s,^cn: ,,g } @search);

Suggestions are welcome!
 
Old 10-25-2005, 07:13 PM   #2
puffinman
Member
 
Registered: Jan 2005
Location: Atlanta, GA
Distribution: Gentoo, Slackware
Posts: 217

Rep: Reputation: 30
How about this? This, however, chomps every line in order to make the result of the second regex control the grep.
Code:
($groupname) = grep {s/\n$//g; s/^cn: //g} @search;
This one only chomps the matching ones. I don't know how I feel about this construct though, as it alters the contents of @search in a sneaky way.
Code:
($groupname) = map {s/\n$//g} grep {s/^cn: //g} @search;
 
Old 10-26-2005, 06:53 AM   #3
apeekaboo
Member
 
Registered: Apr 2003
Location: Stockholm/Sweden
Distribution: Kubuntu, Debian, Slax
Posts: 91

Original Poster
Rep: Reputation: 16
Thanks for your reply!

Your first example is good enough.
I guess it's the paranthesis around the scalar that does the magic, besides from the obvious stripping of newline.
Unfortunately the the stripping of newline in the list does a little too much damage, should I ever want to extract something else later on.

Would you care to explain what the paranthesis does?
I know that without them, only the number of objects in the list is displayed.

I liked this code:
Code:
chomp (($groupname) = grep {s,^cn: ,,gi} @search);
or perhaps this, for better readability:
Code:
($groupname) = grep {s,^cn: ,,gi} @search;
chomp $groupname;
I didn't know I could do without the $_ when using grep.
 
Old 10-26-2005, 08:36 PM   #4
puffinman
Member
 
Registered: Jan 2005
Location: Atlanta, GA
Distribution: Gentoo, Slackware
Posts: 217

Rep: Reputation: 30
Quote:
Would you care to explain what the paranthesis does?
Ah, the subtleties of perl. The parenthesis around the left hand argument tell perl to evaluate the answer in a list context, rather than a scalar context. In a scalar context, the left hand argument is assigned the number of elements in the list (this is usually used to determine whether or not a list is empty, since it's rare to actually need to know how many elements there are in order to iterate - we have the foreach (@list) construct instead). In a list context, a list on the right hand side will be matched up to the elements of the list on the left side. If there aren't enough elements on the left, the superfluous ones on the right are dropped. If there are too many on the left, the superfluous ones are assigned undef.

Quote:
I didn't know I could do without the $_ when using grep.
Yes, the s/// and m// operators always bind by default to $_, it doesn't matter where the code occurs. "$_ =~" is never necessary. By the way, your use of the comma as delimiter is highly unusual (slashes are much more common). Where did you pick that up?
 
Old 10-27-2005, 12:27 AM   #5
apeekaboo
Member
 
Registered: Apr 2003
Location: Stockholm/Sweden
Distribution: Kubuntu, Debian, Slax
Posts: 91

Original Poster
Rep: Reputation: 16
Thanks for explaining!

Quote:
Originally posted by puffinman
Yes, the s/// and m// operators always bind by default to $_, it doesn't matter where the code occurs. "$_ =~" is never necessary. By the way, your use of the comma as delimiter is highly unusual (slashes are much more common). Where did you pick that up?
I don't really like using $_ in the code and I think it's easier to read without it.
Using commas (usually) instead of slashes enhances readability as well. I think I read about it in Perl Black Book, or perhaps even in the Camel. Most charachters are valid:
s,,,
s|||
s!!!
s###
s%%%
...and so on.

I usually pick a delimiter, choosing from comma and slash, which makes the regexp easier to read.
Regexps with lots of \n and \d looks awful with slash as a delimiter. Regexps with periods like (abc...gh.*) might look better with slashes.

If readability is not a priority, you can even use:
s...
s\\\
s???
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
a vector containing lists Kroenecker Programming 3 07-23-2005 01:03 AM
perl: passing 2 individual arrays/lists as args johnMG Programming 12 04-18-2005 03:49 PM
perl(Cwd) perl(File::Basename) perl(File::Copy) perl(strict)....What are those? Baldorg Linux - Software 1 11-09-2003 08:09 PM
What's the easiest way to do this? lectraplayer Linux - Newbie 4 06-10-2003 06:20 PM
Mailing Lists... Nezar Linux - Networking 0 03-25-2002 01:11 AM


All times are GMT -5. The time now is 10:55 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration