CLOSE

A possible solution for the loginpid.pl program is as follows:

  1. #! /usr/bin/perl
  2.  
  3. # loginpid.pl - print the login name and process id (PID) from
  4. # each line of "psout". Print a count of processes.
  5. #
  6. # The "psout" file contains the output of the ps command. The
  7. # first line contains column headers. Each line after that contains
  8. # an entry for each process running on the machine. The first field
  9. # is the username (login id), the second field is the process id (PID),
  10. # and the remaining fields have additional information. For the purpose
  11. # of this program, you only need to capture the first two columns and
  12. # keep a total of the number of processes. Print the header row
  13. # (the first two titles) but don't count it.
  14. #
  15. # USER PID START TIME COMMAND
  16. # krish 396 Oct01 0:03 sshd: krish@pts/3
  17. # krish 397 Oct01 0:00 -ksh
  18. # bedros 1299 Oct06 0:00 /bin/bash /g/home/pbs/torq...
  19. #
  20. # This selection has 3 processes and the first two columns are:
  21. #
  22. # USER PID
  23. # krish 396
  24. # krish 397
  25. # bedros 1299
  26.  
  27. use strict;
  28. use warnings;
  29.  
  30. use IO::File;
  31.  
  32. # open the file "psout" for reading, $fh contains a filehandle
  33. my $fh = IO::File->new("<psout") or die $!;
  34.  
  35. my $count = 0;
  36.  
  37. # read the file, line by line
  38. my $line;
  39. while ($line = <$fh>)
  40. {
  41. # pattern will match just the first two columns
  42. # first column is a login name, containing word characters
  43. # we also include the space after the login name to
  44. # preserve column alignment
  45. # second column is a number, except on the header line, when
  46. # it is the word "PID"
  47. # the remainder of the line can be anything
  48. if ($line =~ /^(\w+\s+)(PID|\d+)\s.*$/)
  49. {
  50. print $1, $2, "\n"; # print captured fields
  51. $count++; # increment count
  52. }
  53. }
  54.  
  55. # close the file
  56. $fh->close;
  57.  
  58. # print total
  59. printf("TOTAL PROCESSES = %d\n", ($count - 1));
  60.  

Another possible solution is:

  1. #! /usr/bin/perl
  2.  
  3. # loginpid.pl - print the login name and process id (PID) from
  4. # each line of "psout". Print a count of processes.
  5. #
  6. # The "psout" file contains the output of the ps command. The
  7. # first line contains column headers. Each line after that contains
  8. # an entry for each process running on the machine. The first field
  9. # is the username (login id), the second field is the process id (PID),
  10. # and the remaining fields have additional information. For the purpose
  11. # of this program, you only need to capture the first two columns and
  12. # keep a total of the number of processes. Print the header row
  13. # (the first two titles) but don't count it.
  14. #
  15. # USER PID START TIME COMMAND
  16. # krish 396 Oct01 0:03 sshd: krish@pts/3
  17. # krish 397 Oct01 0:00 -ksh
  18. # bedros 1299 Oct06 0:00 /bin/bash /g/home/pbs/torq...
  19. #
  20. # This selection has 3 processes and the first two columns are:
  21. #
  22. # USER PID
  23. # krish 396
  24. # krish 397
  25. # bedros 1299
  26.  
  27. use strict;
  28. use warnings;
  29.  
  30. use IO::File;
  31.  
  32. # open the file "psout" for reading, $fh contains a filehandle
  33. my $fh = IO::File->new("<psout") or die $!;
  34.  
  35. my $count = 0;
  36.  
  37. # read the file, line by line, using the default $_ variable
  38. # implicitly for all operations
  39. while (<$fh>)
  40. {
  41. # pattern will match just the first two columns
  42. # first column is a login name, containing word characters
  43. # we also include the space after the login name to
  44. # preserve column alignment
  45. # second column is a number, except on the header line, when
  46. # it is the word "PID"
  47. # the remainder of the line can be anything
  48. # use the substitute s/// operator to change the line in place
  49. s/^(\w+\s+)(PID|\d+)\s.*$/\1\2/; # eliminate all but first 2 fields
  50. print; # print modified line
  51. $count++; # increment count
  52. }
  53.  
  54. # close the file
  55. $fh->close;
  56.  
  57. # print total
  58. printf("TOTAL PROCESSES = %d\n", ($count - 1));
  59.  

A third possible solution is:

  1. #! /usr/bin/perl
  2.  
  3. # loginpid.pl - print the login name and process id (PID) from
  4. # each line of "psout". Print a count of processes.
  5. #
  6. # The "psout" file contains the output of the ps command. The
  7. # first line contains column headers. Each line after that contains
  8. # an entry for each process running on the machine. The first field
  9. # is the username (login id), the second field is the process id (PID),
  10. # and the remaining fields have additional information. For the purpose
  11. # of this program, you only need to capture the first two columns and
  12. # keep a total of the number of processes. Print the header row
  13. # (the first two titles) but don't count it.
  14. #
  15. # USER PID START TIME COMMAND
  16. # krish 396 Oct01 0:03 sshd: krish@pts/3
  17. # krish 397 Oct01 0:00 -ksh
  18. # bedros 1299 Oct06 0:00 /bin/bash /g/home/pbs/torq...
  19. #
  20. # This selection has 3 processes and the first two columns are:
  21. #
  22. # USER PID
  23. # krish 396
  24. # krish 397
  25. # bedros 1299
  26.  
  27. use strict;
  28. use warnings;
  29.  
  30. use IO::File;
  31.  
  32. # open the file "psout" for reading, $fh contains a filehandle
  33. my $fh = IO::File->new("<psout") or die $!;
  34.  
  35. # read the file into array, all at once
  36. my @lines = <$fh>;
  37.  
  38. # modify all lines, eliminating all but first two fields
  39. map { s/^(\w+\s+)(PID|\d+).*$/\1\2/, $_ } @lines;
  40.  
  41. # close the file
  42. $fh->close;
  43.  
  44. # print the modified list of lines
  45. print @lines;
  46.  
  47. # print the total (the highest index is the size - 1, which is what we
  48. # want since the first line is a column header line.
  49. printf("TOTAL PROCESSES = %d\n", $#lines);
  50.  

CLOSE