simple windows process list

2004-09-21 Thread JP
The object of the code below is to output a list of space seperated fields
with PID, username and process. The code generates te correct output. My
guess is that my perl code can be smaller. Who dares?

#!perl
#
# Object:
#  To output a tab separated list of PID, username and process
#  for windows XP
#
# Prerequisites:
#  1) ActiveState Perl
#  2) Windows XP

use warnings;
use strict;

for my $line (`tasklist /v /nh`) {
 chomp($line);
 if ( $line ne  ) {
  # extract PID
  my $pid = substr($line, 26, 6);
  # remove leading spaces
  $pid =~ s/^ *([0-9]+)$/$1/g;

  # extract username
  my $user = substr($line, 88, 50);
  # remove trailing spaces
  $user =~ s/^(.*\S)\s+$/$1/g;
  # change spaces in username to underscores
  $user =~ s/\s/\_/g;

  # extract process
  my $proc = substr($line, 0, 24).substr($line, 152, 72);
  # change multiple spaces to single spaces
  $proc =~ s/\s\s\s*/ /g;
  # remove trailing space
  $proc =~ s/\s$//g;
  # remove trailing N/A
  $proc =~ s/ N\/A$//g;

  # print tab seperated fields
  print $pid,  , $user,  , $proc, \n;
 }
}



-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: simple windows process list

2004-09-21 Thread Peter Scott
In article [EMAIL PROTECTED],
 [EMAIL PROTECTED] (Jp) writes:
The object of the code below is to output a list of space seperated fields
with PID, username and process. The code generates te correct output. My
guess is that my perl code can be smaller. Who dares?

Don't care about smaller.  Care about clearer.  Sometimes the two
go together.

#!perl
#
# Object:
#  To output a tab separated list of PID, username and process
#  for windows XP
#
# Prerequisites:
#  1) ActiveState Perl
#  2) Windows XP

use warnings;
use strict;

for my $line (`tasklist /v /nh`) {
 chomp($line);
 if ( $line ne  ) {

Avoid creating a whole new block by instead writing:
$line ne  or next;

  # extract PID
  my $pid = substr($line, 26, 6);
  # remove leading spaces
  $pid =~ s/^ *([0-9]+)$/$1/g;

Why check for digits?  What's going to go wrong if you don't?

  # extract username
  my $user = substr($line, 88, 50);
  # remove trailing spaces
  $user =~ s/^(.*\S)\s+$/$1/g;
  # change spaces in username to underscores
  $user =~ s/\s/\_/g;

Why?

  # extract process
  my $proc = substr($line, 0, 24).substr($line, 152, 72);
  # change multiple spaces to single spaces
  $proc =~ s/\s\s\s*/ /g;

This is usually written as s/\s+/ /g. even though
technically there is a redundancy there.  Or if you
really mean 'space' and not 'white space', you can do:
$proc =~ tr/ //s;

  # remove trailing space
  $proc =~ s/\s$//g;
  # remove trailing N/A
  $proc =~ s/ N\/A$//g;

  # print tab seperated fields
  print $pid,  , $user,  , $proc, \n;

I don't see any tabs there.  Try this:
print $pid\t$user\t$proc\n;

 }
}

It is better design to have a subroutine that returns the
values you want than to print them so close to having 
figured them out.  One day you may want to do something
other than printing them and you would like to be able to
use the same code.

-- 
Peter Scott
http://www.perldebugged.com/
*** NEW *** http://www.perlmedic.com/



-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




RE: simple windows process list

2004-09-21 Thread Bob Showalter
JP wrote:
 The object of the code below is to output a list of space seperated
 fields with PID, username and process. The code generates te correct
 output. My guess is that my perl code can be smaller. Who dares?

unpack() with 'A' is handy for extracting and removing trailing blanks in
one step.

  for (grep /\S/, `tasklist /v /nh`) {
  chomp;
  my ($proc, $pid, $user, $title) = unpack 'A24 A8 x56 A50 x14 A*', $_;
  $proc = $proc $title unless $title eq 'N/A';
  $proc =~ s/ +/ /g;  # compress multiple spaces
  $pid += 0;  # convert to number
  $user =~ tr/ /_/;   # change blanks to underscores
  print join(\t, $pid, $user, $proc), \n;
  }

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: simple windows process list

2004-09-21 Thread Errin Larsen
On 21 Sep 2004 13:03:21 -, Peter Scott [EMAIL PROTECTED] wrote:
 In article [EMAIL PROTECTED],
  [EMAIL PROTECTED] (Jp) writes:
 The object of the code below is to output a list of space seperated fields
 with PID, username and process. The code generates te correct output. My
 guess is that my perl code can be smaller. Who dares?
 
 Don't care about smaller.  Care about clearer.  Sometimes the two
 go together.
 

SNIP

 
 It is better design to have a subroutine that returns the
 values you want than to print them so close to having
 figured them out.  One day you may want to do something
 other than printing them and you would like to be able to
 use the same code.
 
 --
 Peter Scott
 http://www.perldebugged.com/
 *** NEW *** http://www.perlmedic.com/
 


Hi JP,

I implemented some of Peter's suggestions for you, including making
the meat of this code a subroutine for future use.

Here's the sub:
sub proclist {
my %output;
foreach my $line ( `tasklist /v /nh` ) {
chomp( $line );
$line ne  or next;
# extract PID
my $pid = substr($line, 26, 6);
# remove leading spaces
$pid =~ s/^\s*//;

# extract username
my $user = substr($line, 88, 50);
# remove trailing spaces
$user =~ s/\s*$//;

# extract process
my $proc = substr($line, 0, 24).substr($line, 152, 72);
# change multiple spaces to single spaces
$proc =~ s/\s+/ /g;
# remove trailing N/A
$proc =~ s/N\/A\s*$//g;

# build the return hash
$output{$pid} = join( ':', $user, $proc );
}
return %output;
}

And here's some code that uses that sub to produce the output you were
looking for:

#!perl
#
# Object:
#  To output a tab separated list of PID, username and process
#  for windows XP
#
# Prerequisites:
#  1) ActiveState Perl
#  2) Windows XP

use warnings;
use strict;

# here is an example of using the sub 'proclist' to produce the output
# you described.  Notice that 
#   split(':', $proclisthash{$pid})
# will seperate the user info from the process info for you
my %plist = proclist();

foreach my $pid( keys %plist ) {
my( $out_pid, $out_user, $out_proc ) = ( $pid, split( ':', $plist{$pid} ) );

print $out_pid\t$out_user\t$out_proc\n;
}

cheers,
--Errin

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: simple windows process list

2004-09-21 Thread JP
Cool! I'm down to 161 bytes now, short enough for a oneliner at the C:\
prompt.

for(grep/\S/,`tasklist /v /nh`){
chomp;my($p,$i,$u,$t)=unpack'A24A8x56A50x14A*',$_;$p=$p $tunless$t
eq'N/A';$p=~s/ +/ /g;$i+=0;$u=~tr/ /_/;print$i $u $p\n}

Don't worry guys, my other scripts are far more readable :-)

JP


Bob Showalter [EMAIL PROTECTED] wrote in message
news:[EMAIL PROTECTED]
 JP wrote:
  The object of the code below is to output a list of space seperated
  fields with PID, username and process. The code generates te correct
  output. My guess is that my perl code can be smaller. Who dares?

 unpack() with 'A' is handy for extracting and removing trailing blanks in
 one step.

   for (grep /\S/, `tasklist /v /nh`) {
   chomp;
   my ($proc, $pid, $user, $title) = unpack 'A24 A8 x56 A50 x14 A*',
$_;
   $proc = $proc $title unless $title eq 'N/A';
   $proc =~ s/ +/ /g;  # compress multiple spaces
   $pid += 0;  # convert to number
   $user =~ tr/ /_/;   # change blanks to underscores
   print join(\t, $pid, $user, $proc), \n;
   }



-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response