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]
 




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]
 




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.
> 

<>

> 
> 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]
 




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 $t"unless$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]