[Perl] Different printf formating for different print options


 
Thread Tools Search this Thread
Top Forums Programming [Perl] Different printf formating for different print options
# 1  
Old 03-04-2013
[Perl] Different printf formating for different print options

Hi,

Struggling with single quotes, double quotes, etc.
I want to print a header line, followed by lines with actual values, based on a print option.
In real life it is going to be something like 15 print options and 50 values.
Output will be 1 header and several value lines.
In this example I have just 3 print options and 5 values.
Output is just 1 header and one value line.

For some reason I cannot get it working.
I get uninitialized values and quotes where I do not want them.
It expects too many values (seen by the extra comma's in the output).
And therefore I could use some expert help.

Here the example.pl code to make it, hopefully, more clear.

Code:
#!/bin/perl -w #-d
use strict;

my $PrintOption = $ARGV[0] || 0;

my $Value1 = "one";
my $Value2 = "two";
my $Value3 = "three";
my $Value4 = "four";
my $Value5 = "five";

my $PrintFormat;
my $PrintFormat1 = q(%s);
my $PrintFormat23 = q(%s,%s);
my $PrintFormat45 = q(%s,%s);

my $PrintHeader;
my $PrintHeader1 = q("Value1");
my $PrintHeader23 = q("Value2","Value3");
my $PrintHeader45 = q("Value4","Value5");

my $PrintValues;
my $PrintValue1 = $Value1;
my $PrintValue23 = qq($Value2,$Value3);
my $PrintValue45 = qq($Value4,$Value5);

if ( $PrintOption eq 1 ) {
  $PrintFormat = "$PrintFormat1,$PrintFormat23";
  $PrintHeader = "$PrintHeader1,$PrintHeader23";
  $PrintValues = "$PrintValue1,$PrintValue23";
  printf "Expected Output with PrintOption %s\n\n", $PrintOption;
  printf "%s,%s,%s\n", "Value1","Value2","Value3";
  printf "%s,%s,%s\n", $Value1,$Value2,$Value3;
} elsif ( $PrintOption eq 2 ) {
  $PrintFormat = "$PrintFormat1,$PrintFormat45";
  $PrintHeader = "$PrintHeader1,$PrintHeader45";
  $PrintValues = "$PrintValue1,$PrintValue45";
  printf "Expected Output with PrintOption %s\n\n", $PrintOption;
  printf "%s,%s,%s\n", "Value1","Value4","Value5";
  printf "%s,%s,%s\n", $Value1,$Value4,$Value5;
} else {
  $PrintFormat = "$PrintFormat1,$PrintFormat23,$PrintFormat45";
  $PrintHeader = "$PrintHeader1,$PrintHeader23,$PrintHeader45";
  $PrintValues = "$PrintValue1,$PrintValue23,$PrintValue45";
  printf "Expected Output with PrintOption %s\n\n", $PrintOption;
  printf "%s,%s,%s,%s,%s\n", "Value1","Value2","Value3","Value4","Value5";
  printf "%s,%s,%s,%s,%s\n", $Value1,$Value2,$Value3,$Value4,$Value5;
}

printf "\nActual Output with PrintOption %s\n\n", $PrintOption;
printf $PrintFormat, $PrintHeader;
printf "\n";
printf $PrintFormat, $PrintValues;
printf "\n";

Result:

Code:
# ./example.pl 1
Expected Output with PrintOption 1

Value1,Value2,Value3
one,two,three

Actual Output with PrintOption 1

Use of uninitialized value in printf at ./example.pl line 51.
Use of uninitialized value in printf at ./example.pl line 51.
"Value1","Value2","Value3",,
Use of uninitialized value in printf at ./example.pl line 53.
Use of uninitialized value in printf at ./example.pl line 53.
one,two,three,,

---------- Post updated at 02:17 PM ---------- Previous update was at 10:08 AM ----------

When I use:

Code:
  printf $PrintFormat, "Value1","Value2","Value3";
  printf $PrintFormat, $Value1,$Value2,$Value3;

I get the right output:

Code:
Value1,Value2,Value3
one,two,three

With:

Code:
 printf $PrintFormat, $PrintHeader;
 printf $PrintFormat, $PrintValue23;

I get:

Code:
Use of uninitialized value in printf at ./ej.pl line 32.
Use of uninitialized value in printf at ./ej.pl line 32.
"Value1","Value2","Value3"
,,
Use of uninitialized value in printf at ./ej.pl line 34.
Use of uninitialized value in printf at ./ej.pl line 34.
two,three,,

Some debugging info:

Code:
  DB<1> x $PrintFormat
0  '%s,%s,%s
'
  DB<2> x $PrintHeader
0  '"Value1","Value2","Value3"
'
  DB<3> x $PrintValues
0  'one,two,three'

  DB<4> printf $PrintFormat, "1", "2", "3";
1,2,3

The 'problem' is that $PrintHeader is seen as 1 string for the printf command.
That is why I get 2 uninitialized values.

---------- Post updated at 03:19 PM ---------- Previous update was at 02:17 PM ----------

This works.
Perhaps not very prety, but it does the job.
Had to use arrays.
And using a string is a bit more easy than using a variable, when working with arrays.
But I am just an amateur.
Always open for suggestion on how to make it more simple.

Code:
#!/bin/perl -w #-d
use strict;

my $PrintOption = $ARGV[0] || 0;

my $Value1 = "one";
my $Value2 = "two";
my $Value3 = "three";
my $Value4 = "four";
my $Value5 = "five";

my $PrintFormat;
my $PrintFormat1 = q(%s);
my $PrintFormat23 = q(%s,%s);
my $PrintFormat45 = q(%s,%s);

my @PrintHeader;
my @PrintHeader1 = qw(Value1);
my @PrintHeader23 = qw(Value2 Value3);
my @PrintHeader45 = qw(Value4 Value5);

my @PrintValues;
my @PrintValue23;
my @PrintValue45;
my @PrintValue1 = qq($Value1);
push (@PrintValue23, $Value2, $Value3);
push (@PrintValue45, $Value4, $Value5);

if ( $PrintOption eq 1 ) {
  $PrintFormat = "$PrintFormat1,$PrintFormat23\n";
  @PrintHeader = (@PrintHeader1,@PrintHeader23);
  @PrintValues = (@PrintValue1,@PrintValue23);
  printf "Expected Output with PrintOption %s\n\n", $PrintOption;
  printf "%s,%s,%s\n", "Value1","Value2","Value3";
  printf "%s,%s,%s\n", $Value1,$Value2,$Value3;
} elsif ( $PrintOption eq 2 ) {
  $PrintFormat = "$PrintFormat1,$PrintFormat45\n";
  @PrintHeader = (@PrintHeader1,@PrintHeader45);
  @PrintValues = (@PrintValue1,@PrintValue45);
  printf "Expected Output with PrintOption %s\n\n", $PrintOption;
  printf "%s,%s,%s\n", "Value1","Value4","Value5";
  printf "%s,%s,%s\n", $Value1,$Value4,$Value5;
} else {
  $PrintFormat = "$PrintFormat1,$PrintFormat23,$PrintFormat45\n";
  @PrintHeader = (@PrintHeader1,@PrintHeader23,@PrintHeader45);
  @PrintValues = (@PrintValue1,@PrintValue23,@PrintValue45);
  printf "Expected Output with PrintOption %s\n\n", $PrintOption;
  printf "%s,%s,%s,%s,%s\n", "Value1","Value2","Value3","Value4","Value5";
  printf "%s,%s,%s,%s,%s\n", $Value1,$Value2,$Value3,$Value4,$Value5;
}

printf "\nActual Output with PrintOption %s\n\n", $PrintOption;
printf $PrintFormat, @PrintHeader;
printf $PrintFormat, @PrintValues;

# 2  
Old 03-06-2013
Code:
$
$
$ cat -n example_2.pl
     1  #!/usr/bin/perl -w
     2  use strict;
     3  my $option = $ARGV[0];
     4  my %x = (
     5            0,
     6              [
     7                [ qw (%s %s %s %s %s) ],                      # format array ref
     8                [ qw (Value1 Value2 Value3 Value4 Value5) ],  # header array ref
     9                [ qw (one two three four five) ]              # data array ref
    10              ],
    11            1,
    12              [
    13                [ qw (%s %s %s) ],
    14                [ qw (Value1 Value2 Value3) ],
    15                [ qw (one two three) ]
    16              ],
    17            2,
    18              [
    19                [ qw (%s %s %s) ],
    20                [ qw (Value1 Value4 Value5) ],
    21                [ qw (one four five) ]
    22              ]
    23          );
    24  $option = 0 if (! defined $option) or (! defined $x{$option});
    25
    26  my $fmt  = join(",", @{$x{$option}->[0]})."\n";
    27  my @hdr  = @{$x{$option}->[1]};
    28  my @data = @{$x{$option}->[2]};
    29
    30  printf ($fmt, @hdr);
    31  printf ($fmt, @data);
$
$ perl example_2.pl 1
Value1,Value2,Value3
one,two,three
$
$ perl example_2.pl 2
Value1,Value4,Value5
one,four,five
$
$ perl example_2.pl 3
Value1,Value2,Value3,Value4,Value5
one,two,three,four,five
$
$ perl example_2.pl 4
Value1,Value2,Value3,Value4,Value5
one,two,three,four,five
$
$ perl example_2.pl 0
Value1,Value2,Value3,Value4,Value5
one,two,three,four,five
$
$ perl example_2.pl
Value1,Value2,Value3,Value4,Value5
one,two,three,four,five
$
$

# 3  
Old 03-06-2013
I have been there so many times.

Put each header option in a subroutine.

Build the line with one line one element printf statements, not a long template and a long argument list. It will be more readable, more maintainable, easy to comment and likely runs faster. After all, output is a stream, so throw the pieces into the stream one at a time. Here is a fragment of JAVA I wrote recently:
Code:
System.out.print( " " );
System.out.print( creditorName );
System.out.print( " " );
System.out.format( "%8.2f", new Double( d[0] )); // creditorBalance
System.out.print( " " );
System.out.print( s[5] ); // mailDate
System.out.println( " S CMT" );
recCt++ ;


Last edited by DGPickett; 03-06-2013 at 04:18 PM..
# 4  
Old 03-07-2013
Quote:
Originally Posted by durden_tyler
Code:
     9                [ qw (one two three four five) ]              # data array ref

Thanks for taking time to reply and for your suggestion.

Could you try to replace the data by variables (my $Value1 = "one", etc) and then try again ?

I get this:

Code:
Value1,Value2,Value3,Value4,Value5
$Value1,$Value2,$Value3,$Value4,$Value5

The only way to make it work was using arrays for the values iso strings.
See the last part of the first post (I am having difficulties in replying to my own post in a separate post).

---------- Post updated at 03:23 PM ---------- Previous update was at 03:19 PM ----------

Quote:
Originally Posted by DGPickett
Here is a fragment of JAVA I wrote recently:
Would have to convert this idea to Perl and then have it shaped to my problem.
I find a solution already (last part of the first post) and that works for me.

Thanks for the reply though.
# 5  
Old 03-07-2013
Quote:
Originally Posted by ejdv
...
Could you try to replace the data by variables (my $Value1 = "one", etc) and then try again ?

I get this:

Code:
Value1,Value2,Value3,Value4,Value5
$Value1,$Value2,$Value3,$Value4,$Value5

...
That's because you are using the qw operator with your variables. It's not the same.

perlop - perldoc.perl.org
# 6  
Old 03-07-2013
I'm just saying that for good code structure, especially in printf situaitons where a template bit matches a data argument, doing one at a time give you a virtual array of lines where the template is right by the data and any comment, one field a line, give or take the occasional adjacent series of constants.

At a higher level, put all or minority record types in separate subroutines, so the flow is simple to follow: writeHeader, while ... writeData, writeTrailer.
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

How to combine print and printf on awk

# cat t.txt 2,3,4,5,A,2012-01-01 00:00:28 2,6,4,5,A,2012-01-02 00:00:28 2,7,4,5,A,2012-01-02 02:00:28 # awk -F"," '{OFS=",";print $2,"";printf("%s", strftime("%m%d%y",$6));printf("%s", strftime("%H%M%S \n",$6));print ("",$1)}' t.txt 3, 010170073332 ,2 6, 010170073332 ,2 7,... (3 Replies)
Discussion started by: before4
3 Replies

2. Shell Programming and Scripting

What's the difference between print and printf in command?

For example, in this command: ls /etc/rc0.d/ -print ls /etc/rc0.d/ -printfThe outputs are quite different, why? (7 Replies)
Discussion started by: Henryyy
7 Replies

3. Shell Programming and Scripting

Formating of query variable in perl

Hi , I am facing error in perl when I assign a below query in a varibale $query because of new line charchters $query= SELECT XYZ , ABC , c2 , c3 , c4 FROM t1 how can i get rid of new line charchters with out changing the... (2 Replies)
Discussion started by: gvk25
2 Replies

4. UNIX for Advanced & Expert Users

remove print formating from printer output file

I have a print file taken from the print spooler and I want to delete all the formatting leaving only the text. If you vi the file it shows "\304\304 ...." which translates into a printed line on print output. I need to be able to edit and pass this file to another process Thnaks (10 Replies)
Discussion started by: petercp
10 Replies

5. Shell Programming and Scripting

How to print a string using printf?

I want to print a string say "str1 str2 str3 str4" using printf. If I try printing it using printf it is printing as follows. output ------- str1 str2 str3 str4 btw I'm working in AIX. This is my first post in this forum :) regards, rakesh (4 Replies)
Discussion started by: enigmatrix
4 Replies

6. Shell Programming and Scripting

file formating in Perl

Hi, I am new to unix , I have a requirement for formating the input file and generate the output file as per the downstream requirement .. My application receiving a text input file having 4 field and my application need to check each field and if some value of a field is blank ..then it need... (1 Reply)
Discussion started by: julirani
1 Replies

7. Shell Programming and Scripting

AWK: formating number without printf

Hello, I wrote a script that does lot of things, and I would like to change the format of a number but without printing it now (so I don't want to use printf as it will print the value immediately). Schematically here is what I have: awk 'BEGIN{number=0.01234567} $1==$2{$3=number}... (5 Replies)
Discussion started by: jolecanard
5 Replies

8. Shell Programming and Scripting

Date Formating in Perl

Hi All, Can anybody tell me why is there a "0" in my output of $date_today ? #!/usr/local/bin/perl $date_today = system "date '+%y%m%d'"; print "$date_today\n"; Output: $ perl test4 080908 0 (3 Replies)
Discussion started by: Raynon
3 Replies

9. Shell Programming and Scripting

How to print a % within a printf() function using awk

Here is the code I'm using { printf("%11d %4.2f\% %4.2f\%\n", $1,$2,$3); } I want the output to look something like 1235415234 12.24% 52.46% Instead it looks something like 319203842 42.27\%4.2f\% How do I just print a "%" without awk or printf thinking I'm trying to do... (1 Reply)
Discussion started by: Awanka
1 Replies

10. Shell Programming and Scripting

formating array file output using perl

Hello, I am trying to output the values in an array to a file. The output needs to be formated such that each array value is left jusified in a field 8 character spaces long. Also, no more than 6 fields on a line. For example: @array= 1..14; Needs to be output to the file like so: 1 ... (4 Replies)
Discussion started by: seismic_willy
4 Replies
Login or Register to Ask a Question