File formating

I need to create a fixed width file based on the column lengths.
lets assume I have six(this may be dynamic) fields each are of different length

  • column1=6 #size of the column
  • column2=3
  • column3=2
  • column4=3
  • column5=4
  • column6=5

I tried below code snippet but it is not working

 echo 'a|b|c|d|e|f' |awk 'BEGIN {IFS = "|";column_length[0]=6;column_length[1]=3;column_length[2]=2;column_length[3]=3;column_length[4]=4;column_length[5]=5}
{{for(i=1;i<=NF;i++){printf " | ";printf("%-$column_length[$i-1]s",$i);printf "|"; if(i==NF){printf("\n")}}}}'
  
 

I want output to be in below format

| a     | b  | c | d   | e   | f    |

To help you get on your way, try:

echo 'a|b|c|d|e|f' |awk 'BEGIN {FS = "|";column_length[0]=6;column_length[1]=3;column_length[2]=2;column_length[3]=3;column_length[4]=4;column_length[5]=5}
{for(i=1;i<=NF;i++) printf("| %-" column_length[i-1] "s",$i); printf("|\n")}'
| a     | b  | c | d  | e   | f    |

--
Note: instead of

printf("| %-" column_length[i-1] "s",$i)

,you can also use:

printf("| %-*s", column_length[i-1],$i) 
1 Like

Hi I am getting below error when I formatted my code

 #!/bin/ksh
set -x
fixed_output_format()
{
 domain=$1
 file_reg=$2
 file_freq=$3
 file_name=$4
 file_counter=$5
 record_cnt=$6
 file_creation_dt=$7
 echo " We are inside Module  "  
  $(echo "$domain | $file_reg | $file_freq | $file_name | $file_counter | $record_cnt | $file_creation_dt " |
  awk 'BEGIN
       {
        FS = "|";
        column_length[0]=6;
        column_length[1]=3;
        column_length[2]=2;
        column_length[3]=3;
        column_length[4]=4;
        column_length[5]=5;
        column_length[6]=6;
       }
       {
        for(i=1;i<=NF;i++)
        printf("| %-" column_length[i-1] "s",$i);
        printf("|\n")
       }' )  >>  OUTPUT_FILE
 }
################
echo " we are the start of script"
fixed_output_format a b c d e f g

 

I am getting below output

awk: cmd. line:1: BEGIN blocks must have an action part

awk doesn't ALWAYS allow for breaking lines. Put the opening { on the same line OR use a "line continuation" character: \ .

In addition to what RudiC and Scrutinizer have already said, why would you write a 28 line Korn shell function using a pipeline of echo and awk to get at awk 's printf function when ksh 's built-in printf utility can do the same thing in 5 lines?

Note that the leading space on the 1st line of your script makes that line just a comment and removes its ability to specify that your script is to be run by /bin/ksh .

#!/bin/ksh
set -x
fixed_output_format()
{	echo " We are inside Module  "  
	printf '|%-6s|%-3s|%-2s|%-3s|%-4s|%-5s|%-6s|\n' \
	    "$1" "$2" "$3" "$4" "$5" "$6" "$7" >> OUTPUT_FILE
 }
################
echo " we are the start of script"
fixed_output_format a b c d e f g

And, note that calling this function fixed_output_format is a misnomer if the arguments you supply to this function contain strings that are longer than the specified field widths. If you really want fixed width output for each field (truncating long input strings), you would want to change:

	printf '|%-6s|%-3s|%-2s|%-3s|%-4s|%-5s|%-6s|\n' \

to:

	printf '|%-6.6s|%-3.3s|%-2.2s|%-3.3s|%-4.4s|%-5.5s|%-6.6s|\n' \

To see what difference this makes, add an additional line to the end of your script:

fixed_output_format 7777777 4444 333 4444 55555 666666 7777777

and look at the last two lines printed into OUTPUT_FILE by the above printf statement suggestions.
With your current format you'd get:

|a     |b  |c |d  |e   |f    |g     |
|7777777|4444|333|4444|55555|666666|7777777|

and with the alternative you'd get:

|a     |b  |c |d  |e   |f    |g     |
|777777|444|33|444|5555|66666|777777|
1 Like