Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Using 'print' statement with fixed width

Posted on 2012-08-31
10
Medium Priority
?
729 Views
Last Modified: 2012-09-02
Hello,

I'm not that comfortable in using 'printf' in Perl. Hence am seeking your help to produce a formatted output using printf statement. To explain my problem, I made a tiny perl script using 'printf'and shown a sample execution of it.


$ cat check.pl
#!/usr/bin/perl

print "Enter the Operating system name : ";
chomp ($OsIssue=<STDIN>);
chomp ($Current_Data = `date`);

system("clear");
printf "\nOperating System                 : %-30s", "$OsIssue";
printf "\t\t\tCurrent System time                : %-30s\n\n", "$Current_Data";


$ perl check.pl
Enter the Operating system name : RedHat Linux 5.8

Operating System                 : RedHat Linux 5.8                                     Current System time              : Fri Aug 31 06:35:28 PDT 2012

$ perl check.pl
Enter the Operating system name : Enterprise Linux Enterprise Linux Server

Operating System                 : Enterprise Linux Enterprise Linux Server                     Current System time              : Fri Aug 31 06:35:38 PDT 2012

$

Open in new window



In the above 2 sample execution, you can notice that if the number of characters of string variable "$OsIssue" is more, the output text "Current System time" is drifting towards right. I don't want that to happen. I want the second print statement should print its text in a fixed width (regardless of number of characters of string "$OsIssue".  Hope I made myself clear. Please let me know how to use the printf or sprintf in a correct way for this type of requirement. Thankyou !
0
Comment
Question by:ashsysad
  • 4
  • 3
  • 3
10 Comments
 
LVL 25

Expert Comment

by:lwadwell
ID: 38354341
As far as I am aware ... perl will overflow (widen) the print for longer values than the format normally permits.  A way around would be substr() the values being printed.
Here is a quick example.
my $x = 1;
for (my $i=1; $i < 12; $i++) {
	$x = $x * 11;
	printf "STR: %-8s  NUM: %6d <<END\n", "."x$i, $x;
}

$x = 1;
for (my $i=1; $i < 12; $i++) {
	$x = $x * 11;
	printf "STR: %-8s  NUM: %6d <<END\n", substr("."x$i,0,8), substr($x,0,6);
}

Open in new window

0
 
LVL 28

Expert Comment

by:FishMonger
ID: 38354350
part of the problem is the use of the \t tabs.

This works correctly for me.
#!/usr/bin/perl

print "Enter the Operating system name : ";
chomp ($OsIssue=<STDIN>);
chomp ($Current_Data = `date`);

system("clear");
printf "%-25s : %-30s\n", 'Operating System', $OsIssue;
printf "%-25s : %-30s\n", 'Current System time', $Current_Data;

Open in new window

0
 

Author Comment

by:ashsysad
ID: 38355043
@FishMonger,  I still couldn't avoid using TAB (\t).  My requirement is to execute both the printf statement in Same line. So the first printf statement shouldn't have new-line character (\n). I'm wondering is there a way to do Right justification.

Operating System                 : Enterprise Linux Enterprise Linux Server                     Current System time              : Fri Aug 31 06:35:38 PDT 2012
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 28

Accepted Solution

by:
FishMonger earned 1000 total points
ID: 38355185
So, you want everything in a single line?  It appeared from your post that you wanted them on separate lines.

If you want everything on a single line, then remove the \t tabs and specify the field lengths. and make sure you specify a length equal to or grater than the longest length of the given field.
printf "%-25s : %-50s", 'Operating System', $OsIssue;
printf "%25s : %-30s\n", 'Current System time', $Current_Data;

Open in new window

0
 

Author Comment

by:ashsysad
ID: 38355366
OK, let me try this and get back to you tomorrow. I'm just packing up from my office.

Have a great weekend !
0
 
LVL 25

Expert Comment

by:lwadwell
ID: 38356450
>> and make sure you specify a length equal to or grater than the longest length of the given field
That was the problem I believe ("the number of characters of string variable "$OsIssue" is more") ... in the original example it was %-30s but the input string "Enterprise Linux Enterprise Linux Server" is 40 chars ... hence it was pushing to the right.

I believe the asker is after a method to stop the pushing to the right when the length is less than the given field.

I suggested use of a substr() on the value to constrain it to the maximum length in the format.  A similar result would occur using Perl's format method e.g.
my $s;
my $y = 1;
format test_line =
STR: @<<<<<<<  NUM: @>>>>> <<END
     $s,            $y
.
for (my $i=1; $i < 12; $i++) {
	$y = $y * 11;
	$s = "."x$i;
	$~ = 'test_line';
	write;
}

Open in new window

0
 
LVL 28

Assisted Solution

by:FishMonger
FishMonger earned 1000 total points
ID: 38357224
I understood what issue the OP referring to.  My suggestion was to estimate the maximum length that would realistically be entered and use that in the printf statement.

Based on the code and info that we've been given I don't see the need to use format and to truncate the field.  Instead, I'd calculate the max length of the fields and use that (plus a little padding) in the printf statement.

#!/usr/bin/perl

use strict;
use warnings;
use List::Util qw(max);

print "Enter the Operating system name : ";
chomp (my $OsIssue = <STDIN>);
chomp (my $Current_Date = `date`);

my $padding = 2;
my $OS_name_length = length $OsIssue;
my $date_length = length $Current_Date;
my $width = max($OS_name_length, $date_length) + $padding;

system("clear");
printf "%-17s %-${width}s",  'Operating System:', $OsIssue;
printf "%25s %-${width}s\n", 'Current System time:', $Current_Date;

Open in new window

If there will be multiple rows with inconsistent field widths, then you could either truncate the fields or build up an AoA of the data and and then calculate the widths as I've demonstrated to construct the printf statement or format spec.
0
 
LVL 25

Expert Comment

by:lwadwell
ID: 38357234
Fair enough - I agree with what you are saying.  I just misunderstood your suggestion.
0
 

Author Comment

by:ashsysad
ID: 38359447
Hello FishMonger,  Your solution really helped me to fix my long-time problem with print statement alignment.  I implemented your solution on the script which am developing and got the expected output.

@lwadwell, Thanks for your help too.
0
 

Author Closing Comment

by:ashsysad
ID: 38359451
Thankyou so much !!!!
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

SSH (Secure Shell) - Tips and Tricks As you all know SSH(Secure Shell) is a network protocol, which we use to access/transfer files securely between two networked devices. SSH was actually designed as a replacement for insecure protocols that sen…
In the first part of this tutorial we will cover the prerequisites for installing SQL Server vNext on Linux.
Six Sigma Control Plans
How to Install VMware Tools in Red Hat Enterprise Linux 6.4 (RHEL 6.4) Step-by-Step Tutorial
Suggested Courses

571 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question