Re^2: Golf: reverse sort /etc/passwd by UID
by jwkrahn (Abbot) on Feb 05, 2013 at 20:27 UTC
|
Does this work?
perl -E"say reverse sort{/(:\d+:)/<=>/(:\d+:)/}<>" /etc/passwd
No, it does not work.
In the sort compare function the current records are in $a and $b but you are not accessing the current record in your example.
The comparison operator <=> puts its operands into scalar context and the match operator in scalar context returns TRUE or FALSE so you are not comparing the contents of the capturing parentheses.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
| [reply] [Watch: Dir/Any] |
|
| [reply] [Watch: Dir/Any] |
|
Re^2: Golf: reverse sort /etc/passwd by UID
by thundergnat (Deacon) on Feb 05, 2013 at 19:58 UTC
|
perl -E"say reverse sort{/(:\d+:)/<=>/(:\d+:)/}<>" /etc/passwd
It's quite possible that I'm being exceedingly dense, but how is this any different from just:
perl -E"say reverse<>" /etc/passwd
? Perhaps you meant
perl -E"say sort{($b=~/:(\d+)/)[0]<=>($a=~/:(\d+)/)[0]}<>" /etc/passwd
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
D'oh! I did omit a couple of bits didn't I (It was (obviously) untested -- I don't have an /etc/passwd).
I tried to remove the $b=~ & $a=~ bits when I noticed that reverse was one character less -- ignoring/forgetting that $_ cannot be both at the same time :(.
I don't think the (...)[0] bits are necessary, without /g only the regex will only return one (the first) match.
This should work? (still untested):
perl -E"say sort{$b=~/:(\d+):/<=>$a=~/:(\d+):/}<>" /etc/passwd
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
No, unfortunately that doesn't work either. A regex match in scalar context returns 1 or 0. It needs to be called in list context to return the value.
>perl -E"print 'foo'=~/(o+)/;"
oo
>perl -E"print scalar 'foo'=~/(o+)/;"
1
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
No, no. It does work (tested and confirmed). See my reply to thundergnat.
NOTE- remember you have to omit the typos though, as I already pointed out. So far, the winner remains:
UPDATE: thundergnat is right that the code below DOESN'T work as intended
perl -e 'print reverse sort{/(:\d+:)/<=>/(:\d+:)/}<>' /etc/passwd
Tommy
A mistake can be valuable or costly, depending on how faithfully you pursue correction
| [reply] [Watch: Dir/Any] [d/l] |
|
|
It's quite possible that I'm being exceedingly dense, but how is this any different from just:
perl -E"say reverse<>" /etc/passwd
UPDATE- we only wanted it to work as described below-- with implicit reassignment of $_ to $a and also to $b.
It's not the same. BrowserUK's solution uses two regexes, each with a capture group. The capture groups implicitly assign to what would be the equivalents of "$a" and "$b". Since the point of this excercise was to save typing (potentially at the loss of clarity), BrowserUK didn't bother wasting precious keystrokes in explicitly assigning the result of the regex capture groups to an "$a" or "$b". Instead, he/she (I don't know BrowserUK personally) just let Perl handle those details. BrowserUK definitely meant what was posted ;~)
Tommy
A mistake can be valuable or costly, depending on how faithfully you pursue correction
| [reply] [Watch: Dir/Any] [d/l] |
Re^2: Golf: reverse sort /etc/passwd by UID
by Tommy (Chaplain) on Feb 05, 2013 at 17:32 UTC
|
UPDATE- as thundergnat correctly points out, the code doesn't work as first intended, at least not without some modification.
Technically it's *possible* that usernames can be completely numeric, but that's outright abusive--borderline illegal, and definitely prone to all kinds of problems.
If I we were dealing with "abusive" uid's, it wouldn't be too hard to add a neg look-behind assertion.
Now, for the meat and potatoes... I did run into some small typos in your code, but after correcting them, it worked. *slow and dramatic golf clap*. I had a hunch it could be done with regexes!! I've said it before, and I'll say it again... you have a dark gift my friend (sarcasm).
[user@host]$ perl -e 'print reverse sort{/(:\d+:))/<=>/(:\d+:/)}<>' /e
+tc/passwd
Unmatched ) in regex; marked by <-- HERE in m/(:\d+:)) <-- HERE / at -
+e line 1.
[user@host]$ perl -e 'print reverse sort{/(:\d+:)/<=>/(:\d+:/)}<>' /et
+c/passwd
Unmatched ( in regex; marked by <-- HERE in m/( <-- HERE :\d+:/ at -e
+line 1.
[user@host]$ perl -e 'print reverse sort{/(:\d+:)/<=>/(:\d+:)/}<>' /et
+c/passwd
...and AWESOMENESS HAPPENS ALMOST HAPPENED!
Read through the rest of the thread for the reason why this awesome snippet didn't quite work as intended...
Tommy
A mistake can be valuable or costly, depending on how faithfully you pursue correction
| [reply] [Watch: Dir/Any] [d/l] |