in reply to Golf: reverse sort /etc/passwd by UID

Does this work?

## typos (see below) corrected perl -E"say reverse sort{/(:\d+:)/<=>/(:\d+:)/}<>" /etc/passwd

(Maybe not if usernames can be all digits?)


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.


Comment on Re: Golf: reverse sort /etc/passwd by UID
Download Code
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
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

      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.

        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
        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
      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
Re^2: Golf: reverse sort /etc/passwd by UID
by jwkrahn (Monsignor) 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.

      It works, using the exact input I specified (as well as my /etc/passwd file...

      UPDATE: see my post about me being wrong...

      Tommy
      A mistake can be valuable or costly, depending on how faithfully you pursue correction

        Notice that your input is already "sorted". All that one liner does is reverse it.