mshafey
mshafey

Reputation: 89

How to align the nth column that has multiple lines

I am having 3 variables that I use printf to align their outputs I know the first env var is one line so the 2nd var as well The problem with the 3rd var is that this variable has huge output hence I would like to list them aligned ( i hope below would clear my question )

** I don't have column command **

I am using

printf "%-20s %-5s %-20s \n" "${OUT}" "${COUNT}" "${DATA}"


OUT11                OUT2  OUT3
----------           ----- --------------
GATE1                14    CU4 CU2 CU9var CU3 CU1 CU11admin CU10opt not_sy 
CU_doonce cutttCU clocal_CU global_CU tivoli_CU 
GATE2                70    gdba_CU cdba_CU vudb_CU tti1_CU tti3_CU tt3_CU
3c2_CU tt3c3_CU tt3c4_CU tt3d1_CU tt3a1_CU tt3u1
3t3_CU tt3t4_CU tt4_CU utt4_CU tt4c1_CU tt4c2_CU
4d1_CU tt4a1_CU tt4u1_CU tt4t1_CU tt4t2_CU tt4t3
tt5_CU tt5c1_CU tt5c2_CU tt5c3_CU tt5c4_CU tt5d1
5t1_CU tt5t2_CU tt5t3_CU tt5t4_CU tt6_CU utt6_CU
6c3_CU tt6c4_CU tt6d1_CU tt6a1_CU tt6u1_CU tt6t1
6t4_CU tt7_CU utt7_CU tt7c1_CU tt7c2_CU tt7c3_CU
7a1_CU tt7u1_CU tt7t1_CU tt7t2_CU tt7t3_CU tt7t4

and I need them as:

OUT11                OUT2  OUT3
----------           ----- --------------
GATE1                14    CU4 CU2 CU9var CU3 CU1 CU11admin CU10opt not_sy 
                           CU_doonce cutttCU clocal_CU global_CU tivoli_CU 
GATE2                70    gdba_CU cdba_CU vudb_CU tti1_CU tti3_CU tt3_CU
                           3c2_CU tt3c3_CU tt3c4_CU tt3d1_CU tt3a1_CU tt3u1
                           3t3_CU tt3t4_CU tt4_CU utt4_CU tt4c1_CU tt4c2_CU
                           4d1_CU tt4a1_CU tt4u1_CU tt4t1_CU tt4t2_CU tt4t3
                           tt5_CU tt5c1_CU tt5c2_CU tt5c3_CU tt5c4_CU tt5d1
                           5t1_CU tt5t2_CU tt5t3_CU tt5t4_CU tt6_CU utt6_CU
                           6c3_CU tt6c4_CU tt6d1_CU tt6a1_CU tt6u1_CU tt6t1
                           6t4_CU tt7_CU utt7_CU tt7c1_CU tt7c2_CU tt7c3_CU
                           7a1_CU tt7u1_CU tt7t1_CU tt7t2_CU tt7t3_CU tt7t4

Upvotes: 0

Views: 661

Answers (3)

RavinderSingh13
RavinderSingh13

Reputation: 133600

Could you please try following.

your_command | awk '
/GATE/{
  val=index($0,$3)
  while(++i<val){
    space=space OFS
  }
}
!/^GATE/{
  $0=space $0
}
1'

One liner:

your_command | awk '/GATE/{val=index($0,$3);while(++i<val){space=space OFS}} !/^GATE/{$0=space $0} 1'

OR as per Ed sir's comment try following:

your_command | awk '
/GATE/{
  space=sprintf("%*s",index($0,$3),"")
}
!/^GATE/{
  $0=space $0
}
1'

Upvotes: 2

kvantour
kvantour

Reputation: 26491

You make use of the following line to print your lines:

$ printf "%-20s %-5s %-20s \n" "${OUT}" "${COUNT}" "${DATA}"

The problem you have is that ${DATA} contains newline characters. We can infer this because you attempt to print a string longer than 20 characters in a 20-character-wide field (your format shows this). It are these newline characters that ensure that your DATA continues at the beginning of the next line. If you want to align them, you have to make a small substitution of your newlines in that variable.

Example:

$ p=$'foo\nbar'
$ printf "%-2s %1s\n" "a" "$p"
a  foo
bar
$ printf "%-2s %1s\n" "a" "${p//$'\n'/$'\n'   }"
a  foo
   bar

You know that the DATA column must start on character 28. So there are 27 characters in front of it (20+1+5+1). So all you need to do is:

$ printf "%-20s %-5s %-20s \n" "${OUT}" "${COUNT}" "${DATA//$'\n'/$'\n'$(printf "%27s" "")}"

This should work in bash or a modern ksh. If you do not have this, and variable substitution does recognize ${var//str/repl}, then you can quicklly postprocess that single line with awk:

$ printf "%-20s %-5s %-20s \n" "${OUT}" "${COUNT}" "${DATA}" \
  | gawk -v RS= '{gsub(ORS,ORS sprintf("%27s",""))}1'

Upvotes: 0

Mika Feiler
Mika Feiler

Reputation: 516

#!/bin/bash
OUT="GATE1"
COUNT="14"
DATA="CU4 CU2 CU9var CU3 CU1 CU11admin CU10opt not_sy CU_doonce cutttCU clocal_CU global_CU tivoli_CU"
while [[ -n $DATA ]]
do
    printf "%-20s %-5s %-20s \n" "${OUT}" "${COUNT}" "${DATA:0:48}"
    OUT=" "
    COUNT=" "
    DATA="${DATA:48}"
done

Upvotes: 0

Related Questions