Perl script

Hi,

I am currently working on a perl script for my collegues that produces an output like this :

Directory /orapkg/ora002/oradata/aora02 has size 134 Mb
Directory /orapkg/ora002/oradata has size 20560 Mb
Directory /orapkg/ora002/oradata/aora01 has size 2038 Mb

Now I would like to have the size sorted on the right. The script is as follows :

sub wanted {
$dir = "$File::Find::dir";

unless ($seen{$dir}++) {
next if ( $dir =~ "lost+found" );
$dm=`du -ks $dir`;
($kb, $path) = split /\s+/, $dm ;
$mb = int( $kb / 1024 );
print "Directory $path has size\t $mb Mb\n";
}
}

I do not know exact how to do this, and it's a while ago since I did my last programming. Anyone an idea, maybe puting this into a hash and later on get the longest value would be the solution. Only I do not understand the work of hashes anymore. Can anyone assist?

I will put my complete script below for the overview. Unfortunetly I do not have File::Find::Rule so please no advise on that :). Any other remarks are more than welcome.

Regs David

#!/opt/perl/bin/perl

use File::Find;

# Determine wether argument is given or not
if (@ARGV[0]) {
$directory = "@ARGV[0]";
}
else {
usage();
}

# Searching starting at your given directory
finddepth(\&wanted, $directory);

# If this dir is unique, start getting total disk usage inclusive sub-dirs
%seen = ();
$total = ();
sub wanted {
$dir = "$File::Find::dir";

unless ($seen{$dir}++) {
next if ( $dir =~ "lost+found" );
$dm=`du -ks $dir`;
($kb, $path) = split /\s+/, $dm ;
$mb = int( $kb / 1024 );
print "Directory $path has size\t $mb Mb\n";
}
}

$total=`du -ks $directory`;
($total_size, $useless) = split /\s+/, $total;
$total_size_mb = int( $total_size / 1024 );
print "\nTotal usage of $directory is $total_size_mb Mb\n\n";

sub usage() {
print "\ndirinfo.pl: Error incorrect usage \n\n";
print "Usage: /usr/local/bin/dirinfo.pl <directory> \n";
print "\t <directory> Is directory start point to check \n\n\n";
exit 1;
}

This seems to be a more difficult problem than it appears to be. I have thought about using a hash but I believe it does not work. Thanks to the flexibility of Perl, you may try to do it like this:

#!/usr/bin/perl -w

@list = (
	[123, '/home/abc'],
	[7123, '/home/def'],
	[200, '/home/ghi'],
	[1234, '/home/jki'],
);

@sortedlist = sort { $$b[0] <=> $$a[0] } @list;
foreach (@sortedlist) {
	print $$_[1], "\t", $$_[0], "\n";
}

Output:

/home/def 7123
/home/jki 1234
/home/ghi 200
/home/abc 123

I have no time to examine your code in detail, but I think you can adapt my code in your program very easily.

Hi,

I found a bad solution, but it is a solution :slight_smile:

sub wanted {
$dir = "$File::Find::dir";

unless ($seen{$dir}++) {
next if ( $dir =~ "lost+found" );
$dm=`du -ks $dir`;
($kb, $path) = split /\s+/, $dm ;
$mb = int( $kb / 1024 );

if \( length\($path\) &lt; 9\) \{
  print "Directory $path has \\t\\t\\t\\t\\t\\t $mb MB \\n";
\}
elsif \( length\($path\) &lt; 17 \) \{
  print "Directory $path has \\t\\t\\t\\t\\t $mb MB \\n";
\}
elsif \( length\($path\) &lt; 25 \) \{
  print "Directory $path has \\t\\t\\t\\t $mb MB \\n";
\}
elsif \( length\($path\) &lt; 33 \) \{
  print "Directory $path has \\t\\t\\t $mb MB \\n";
\}
elsif \( length\($path\) &lt; 41 \) \{
  print "Directory $path has \\t\\t $mb MB \\n";
\}
elsif \( length\($path\) &lt; 49 \) \{
  print "Directory $path has \\t $mb MB \\n";
\}
else \{
  print "Directory $path has  $mb MB \\n";
\}

}
}

Looks awful though. :smiley:

I think you would better use the sort() function if you really are to sort something. If you need to introduce spacing really neatly and reliably, sprintf is the only function I would recommend.

there are alot of way to do your formating.
this is an example from learning perl. useing Formats.

but w/o keeping it KISS i would just use the sprintf function to do your basic formating and it will still look pretty.

#! /usr/bin/perl -w

format STDOUT =
=================================
| @||||||||||||||||||||||||     |
$uname
| @||||||||||||||||||||||||     |
$uid
| @||||||||||||||||||||||||     |
$real_name
=================================
.

open(PASSFILE, "/etc/passwd") || die "Can not open password file";

while (<PASSFILE>) {
($uname, $uid, $real_name)=(split /:/)[0,2,4];
write ;
}

You can probably write out to a file and do a sort on it.

cat file | sort --field-separator=" " -n -k 5.5

Is this an acceptable solution to you?

thats alot of work exspecially if you are writeing a script to do it in the first place.

there are plenty of ways to do what he need in his script w/o going to a manual process.