Surely one of the most annoying things about working in a non-gui environment is convenient formatting. We have all had output that was off due to tabs or new lines or variables that overran their boundaries in the output area, etc. Provisioning for such things can be tedious, time consuming, and highly annoying. Luckily for us, perl provides a text formatting feature that is built in and fairly easy to use.
Let’s assume, for a second, that you have some totally random output from a very unused command that looks something like this:
-rw-r--r-- 1 root root 612084 Apr 14 09:07 131c083cc4.jpg -rw-r--r-- 1 root root 33542 Apr 2 17:26 design.jpg -rw-r--r-- 1 root root 2410 Jun 16 11:04 firefox.gif -rw-r--r-- 1 root root 12097 Apr 2 17:26 header_top_rt.gif -rw-r--r-- 1 root root 5635 Apr 2 17:26 hypervmlogo.gif -rw-r--r-- 1 root root 40462 Apr 2 17:26 laptopdesktop.jpg -rw-r--r-- 1 root root 2551 Apr 2 17:26 mini30x100.jpg -rw-r--r-- 1 root root 1983 May 15 13:23 sql.txt -rw-r--r-- 1 root root 146018 Apr 2 17:26 stonehedge2.jpg -rw-r--r-- 1 root root 79843 Apr 2 17:26 streaming.jpg -rw-r--r-- 1 root root 873 Apr 14 09:07 test.html
And let’s further assume that you want to see only the file name then the owner of that file displayed based on some arbitrary thing like the file size; something like this:
131c083cc4.jp root design.jpg root header_top_rt root laptopdesktop root stonehedge2.j root streaming.jpg root
Well, perl’s format is exactly what we need. Format works like this:
format NAME = formatting template variables to plug in formatting template variables to plug in ... etc .
And when perl runs the “write” command, it takes the variables listed on each line and plugs them into the formatting line above them. If the template line has no argument line, it is just written as text. The formatting starts with either a @ symbol (normal values) or a ^ symbol (multiline text block). Padding is displayed by using either < (left adjust) symbols, > (right adjust) symbols, | (center adjust) symbols or ##.### (numerical value with or without decimal). So in our example above, it would look like so:
format STDOUT = @<<<<<<<<<<<< @>>>>>>>> $info[8], $info[2] .
So first we tell Perl we are formatting STDOUT and then we give it a line of formatting. We tell it we want a left adjusted value that will take up 12 spaces, meaning it will start printing the value on the left-most space and write til it runs out of data for that variable, then it will write spaces til the total number of characters written is 12. then we have a space, followed by a right adjusted, 8 character variable. Then next line we tell it what values we want it to fill. So here is the code all together:
#! /usr/bin/perl -w use strict; die "$0: no size specifiedn" unless $#ARGV == 0; my @info; format STDOUT = @<<<<<<<<<<<< @>>>>>>> $info[8], $info[2] . open(FILES, "ls -la |") || die "Error: unable to open filen"; while() { @info = split; write if ($info[4] >= $ARGV[0]); }
So first we check to make sure we got an argument in, something we can use to compare to the file sizes we are going to look at. Then we specify the formatting we are going to use. Then we open the ls -la command and pipe it into us. We split the items coming in and look at the fourth item (the size) and make sure it is greater than or equal to the file size specified as the argument. If it is, we write it to STDOUT according to the formatting specified above! The output is like so:
131c083cc4.jp root design.jpg root header_top_rt root laptopdesktop root stonehedge2.j root streaming.jpg root
That’s all for this tutorial. Tinker around with it and get formatting to save you time too!
Pingback: Perl Coding School » Blog Archive » perl code [2008-08-05 20:47:14]