Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7971637
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 4, 20262026-06-04T07:41:00+00:00 2026-06-04T07:41:00+00:00

I have a Perl one-liner that works fine on the command line: perl -nle

  • 0

I have a Perl one-liner that works fine on the command line:

perl -nle 'm"\w+:x:\d+:\d+:\S+:/S+:(\S+)$" and $h{$1}++; END{ print "$_: $h{$_}" foreach sort { $h{$b} <=> $h{$a} } keys %h }' /etc/textfile

I’ve put this into a shell file called shell.sh so the next guy won’t have to copy/paste and can just run it:

#!/bin/sh
perl -nle 'm"\w+:x:\d+:\d+:\S+:/S+:(\S+)$" and $h{$1}++; END{ print "$_: $h{$_}" foreach sort { $h{$b} <=> $h{$a} } keys %h }' /etc/textfile

I try running this on the command line and get no results; it just loads a fresh prompt with no output. Anyone see what I’m doing wrong?

Here are some system specs:

Linux version 2.6.32-220.13.1.el6.x86_64

(gcc version 4.4.6 20110731 (Red Hat 4.4.6-3) (GCC)

GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)

Here’s a bit from the text file:

rfink:x:140:140:rat fink:/var/lib/rfink:/sbin/nologin                                 
edible:x:16252:10001:eric idle:/users/eidle/:/bin/bash                                       
tsawyer:x:30855:10001:tom sawyer:/users/tsawyer/:/bin/bash                                
karthur:x:30886:10001:King Arthur:/users/karthur/:/bin/bash                                         
karthur:x:30886:10001:king arthur:/users/karthur/:/bin/bash                                         
jcash:x:30887:10001:john cash:/users/jcash/:/bin/bash                              
hpotter:x:30887:10001:harry potter:/users/hpotter/:/bin/bash                              
triddle:x:30956:10001:tom riddle:/users/triddle/:/bin/bash 
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-04T07:41:01+00:00Added an answer on June 4, 2026 at 7:41 am

    Quick answer

    perl -nle 'm"\w+:x:\d+:\d+:[^:]+:\S+:(\S+)\s*$" and $h{$1}++;
      END{ print "$_: $h{$_}" foreach sort { $h{$b} <=> $h{$a} } keys %h }' \
      /etc/textfile
    

    Your regex had three issues.

    1. The field after the group ID could have spaces, so replace that subpattern with [^:]+ to match one or more non-colon characters.
    2. You used the wrong slash in your subpattern for matching the home directory.
    3. Insert \s* before $ to allow optional trailing whitespace on each line.

    Output:

    /bin/bash: 7
    /sbin/nologin: 1

    Other approaches

    Perl has an awk mode, which would allow

    perl -F: -lane '++$sh{$F[-1]};
      END{print "$_: $sh{$_}" for sort { $sh{$b} <=> $sh{$a} } keys %sh}' \
      /etc/textfile
    

    Having to remove trailing whitespace seems to cancel the syntactic benefit.

    perl -F: -lane '($sh = pop @F) =~ s/\s+$//; ++$sh{$sh};
      END{print "$_: $sh{$_}" for sort { $sh{$b} <=> $sh{$a} } keys %sh}' \
      /etc/textfile
    

    You could use a pipeline to get the best of all worlds:

    perl -pe 's/[^\S\n]+$//' /etc/textfile |
      perl -F: -lane 'print $F[-1]' |
        sort | uniq -c | sort -nr
    

    The output transposes the columns, but you get the same information.

    Note the use of the regex double-negative technique in the pipeline’s first command for removing all whitespace except newlines.

          7 /bin/bash
          1 /sbin/nologin

    As a shell script

    Your question asks for a shell script, so—to vibe off daxim’s answer—that is

    #! /bin/sh
    
    perl -MUser::pwent -le \
      '$_->shell && print $_->shell while $_ = getpwent' |
      sort | uniq -c | sort -nr
    

    Note that this does not handle the pathological case of a shell named 0.

    If you don’t necessarily want to read the system /etc/passwd, then your script becomes

    #! /bin/sh
    
    if [ $# -eq 0 ]; then
      echo Usage: $0 passwd-file .. 1>&2
      exit 1
    fi
    
    perl -pe 's/[^\S\n]+$//' "$@" |
      perl -lne 'm|\w+:x:\d+:\d+:[^:]+:\S+:(\S+)$| && print $1' |
        sort | uniq -c | sort -nr
    

    Different systems use different formats, so I recommend nailing down your expectation as in the above rather than blindly printing the last field, whatever it is. This may mean coping with the occasional empty output.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a perl one-liner in a Makefile to edit files in place: perl
I have a Perl script that launches 2 threads,one for each processor. I need
I have a perl script which when run from the command line generates a
Supposing I have one perl in /usr/bin (which came along with my os-distribution) and
Scenario 1: I have one wrapper Perl script which uses another Perl module and
I have 2 perl modules every module use the second one i.e Module1.pm use
I have one shell script opening a perl script. This perl script should be
I have a Java application which requires certain software (one of them being Perl)
I have Perl code that uses the system() function to call robocopy.exe, but it
I am currently learning Perl. I have Perl hash that contains references to hashes

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.