On Fri, 18 Jan 2002, Matt Johnson wrote:
perl -ne 'print join("\n", split(",",$_) ) if s/^pupil:.*:(.*)$/$1/' /etc/group I don't know whether to laugh or cry! A big thanks. I'll try it out (and I'll check out a few Perl books from Amazon I think too!). It only makes me want more...
FWIW, here's a breakdown of the one-liner: "perl" : pretty obvious "-ne" : the "e" means that the next argument is literal Perl code (i.e. we are putting the Perl on the command line instead of inside a script file), the "n" means "assume a basic program structure that will read in lines one by one from a specified file and execute my Perl code once for each line. "print x if y" : this gets executed for each line in the specified file (which is /etc/group). If y evaluates to true then x will be printed. "s/^pupil:.*:(.*)$/$1/" : the fun bit - a regular expression! s/a/b/ means to do a search and replace (replace a with b) ^ is "beginning of line" pupil:.*: is "pupil:(any number of any character):" (.*) is "any number of any character" $ is "end of line" $1 is a backreference. The part of the line that we want to extract is everything from the final colon up to the end of the line. This gets matched by the bit inside the brackets - ":(.*)$". The $1 refers back to the first bracketed part of the search expression, which is the bit we want to extract. Overall, the effect of this is to search for lines beginning with "pupil:", then to replace the line with everything after the final colon (i.e. the comma-separated list of users). The expression will evaluate to true if it manages to do a search and replace, which will happen only for the line that actually begins "pupil:". split(",",$_) : will take the comma-separated list of users and split it into an array using the comma as a separator. $_ is a special variable in Perl; basically it means "the thing I'm dealing with at the moment". Note that I didn't specify a variable for the search & replace operation; you can often omit a variable name and $_ will be used implicitly. join(" ", ... ) : takes the array created by split() and joins it together into a single line using " " as a separator. /etc/group : the file(s) that we want to use for input. Perl is a very nice language because it's almost never necessary to reinvent the wheel and you can fit an amazing amount of power into a single line. Consider this, for example: ( $user, $pass, $uid, $gid, $fullname, $homedir, $shell ) = split (":"); If $_ contains a line from /etc/passwd then this single line will extract all the relevant fields into variables for us. Combined with the "-ne" option, this means we could do something like: perl -ne '( $user, $pass, $uid, $gid, $fullname, $homedir, $shell ) = split (":"); print "User $user lives in $homedir\n";' /etc/passwd Just a taster of the wonderful world of Perl... Michael