Showing posts with label file size. Show all posts
Showing posts with label file size. Show all posts

Saturday, December 20, 2008

Timing is everything

My file synchroniser needs to know when a file was last modified, in order to decide if this version is newer than the version it's being compared with. Perl provides a very convenient stat() function that includes this, along with a variety of other information.

All we need do is...

use File::stat;

then...

my $StatusBlock = stat($Entry)
or die "Couldn't stat $Entry: $!";
my $LastModified = $StatusBlock->mtime;
print MASTERFILE "$Entry | $LastModified\n";

The first line creates a hash for the file information, the second is a crude handler for any errors, the third extracts the number of seconds since the epoch at which the file was modified and the last prints the file name and the date to my work file.

This is a nice example of Perl's power to simplify something that would otherwise require a lot of code. What's more, it's easy to understand, which is a massive advantage when maintenance is required. Having spent far too long puzzling over obscure code in the wee small hours with frantic managers breathing heavily in my ear, 'easy to understand' seems very good to me.
:

Wednesday, March 15, 2006

Some Awk Tips and Tricks

Finding the length of a line.

A colleague needed to find the length of a particular line in a file. He discovered that using 'wc' gave the wrong result (as in "head -2 filename | tail -1 | wc -c"). Here's what he came up with instead. Note the parentheses...

cat filename | awk '{ if ( NR == 2 ) {print length($0); exit; } } '

Sizing a directory.

This uses Awk's ability to do arithmetic across multiple input lines to produce a count, total and average file size for a directory or a supplied pattern. It's a usefull tool for quick 'n' dirty system admin...

echo "file counter and sizer"
echo "----------------------"
if [[ -z $1 ]]
then
echo "Sizing entire directory"
else
echo "Sizing files for pattern [$1]"
fi

ls -l >/tmp/fsz.$$_1

# -------------------------------
# Remove any directory entries...
# -------------------------------
grep -v ^total /tmp/fsz.$$_1 | grep -v ^d >/tmp/fsz.$$
rm /tmp/fsz.$$_1
# ------------------------
# Set up the search job...
# ------------------------
if [[ -z $1 ]]
then
cat /tmp/fsz.$$
| awk '{s += $5}; END
{printf "\nThere are %d files matching pattern\nAverage size is %f\nTotal size is %f\n", NR, s/NR, s}'

else
grep $1 /tmp/fsz.$$ | awk '{s += $5}; END {printf "\nThere are %d files matching pattern\nAverage size is %f\nTotal size is %f\n", NR, s/NR, s}'
fi
rm /tmp/fsz.$$


Don't use awk - use nawk!

I couldn't work out why this wouldn't work when I ran it using awk (as it worked fine on another machine). It turned out that it would perform admirably if I ran it using nawk instead. It's worth trying this out on your own machine and seeing what happens...

nawk '{ if(substr($0,405,2)=="LS") print $0 }' sourcefile.dat | head -10000 > targetfile.dat
:

Followers

Who is this Sejanus character anyway?

I'm a British freelance Analyst Programmer who has spent the last 25 years working on everything from microcontrollers to mainframes. I use a wide variety of languages at work but try to stick to C and Perl for my own projects.