Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have a script that collects values from a cluster. The values, in some cases, have multiple lines. I have a printf format that specifies how the data should be positioned however, it doesn't take into account multiple lines and therefore the spacing is skewed.

The data should look like this:

Service Group          AutoStart List          System List
foo                    sys1                    sys1
                       sys2                    sys2

Instead it looks like this

Service Group          AutoStart List          System List
foo                    sys1                    
sys2                    sys1
sys2

The AutoStart List and System List should be identical, however regardless of that fact I've not figured out how to force the values into the correct columns.

sgheader="\n\033[4m\033[1m%-30s %-30s %-15s\033[0m\033[0m"
sgformat="\n%-30s %-30s %-15s"



printf "${sgheader}" "Service Group" "Autostart List" "System List" 
printf "${sgformat}" "${svcgroup}" "${autostrtlist}" "${hosts}"
share|improve this question
add comment

3 Answers

up vote 3 down vote accepted

Maybe some thing like:

svcgroup='foo' autostrtlist=$'sys1\nsys2' hosts=$'sys1\nsys2'
paste <(printf '%s\n' "$svcgroup") \
      <(printf '%s\n' "$autostrtlist") \
      <(printf '%s\n' "$hosts") | expand -t30

(ksh93/zsh/bash syntax). Or, POSIXly, on a system with /dev/fd/x:

paste /dev/fd/3 3<<E3 /dev/fd/4 4<<E4 /dev/fd/5 5<<E5 | expand -t 30
$svcgroup
E3
$autostrtlist
E4
$hosts
E5

Except with dash and yash, that one uses temporary files instead of pipes fed by subshells so is likely to be more efficient (in addition to being more portable).

share|improve this answer
1  
This could use a bit of explanation. –  Gilles Jun 23 at 23:32
1  
Isn't it possible that even the second one could use pipes fed by subshells - or, well, pipes anyway? I'm pretty sure dash does it that way, though the chances of it being applied in dash aren't all that big, admittedly. –  mikeserv Jun 24 at 7:21
    
@Gilles, I don't feel that would add much. That would be paraphrasing the code. Please feel free to add one if you like. –  Stéphane Chazelas Jun 24 at 7:42
    
@mikeserv. Indeed. yash as well it seems. –  Stéphane Chazelas Jun 24 at 7:44
    
Hmmm... I've never heard of yash. A 4k shell thought-experiment... BUGS: CNTL-D reruns the previous command instead of exiting the shell. curious. Thanks, Stephane. It sure doesn't have much to hide. –  mikeserv Jun 24 at 7:48
show 5 more comments

You can remove any new lines from a variable.

var=$(echo "$var" | tr -d '\n')
share|improve this answer
add comment

If they'll all fit on one line every time then these are a few easy ways. If you want to this the exact way you are asking for it is going to take more effort to get the columns lined up right. Here is the basic idea:

#!/bin/bash

inputA="foo"
inputB=$'sys1\nsys2\n'
inputC=$'sys1\nsys2\n'

sgheader="\033[4m\033[1m%-30s %-30s %-15s\033[0m\033[0m\n"
sgformat="%-30s %-30s %-15s\n"

printf "${sgheader}" "Service Group" "Autostart List" "System List"

# This shows two simple ways to do this which use concatenation but
# require that the result still fit in the same space as is used for
# a single line
columnA="$inputA"
columnB=$(echo "$inputB"|awk '{printf("%s,",$0)}'|sed 's/,.\s*$//')
columnC=$(echo "$inputC"|tr '\n' ',')

printf "${sgformat}" "${columnA}" "${columnB}" "${columnC}"

# This is a version which outputs like originally asked. It is much harder
# to tweak the formatting of this version though.
pr -tm <(printf '%s\n' "$inputA") <(printf '%s\n' "$inputB") \
       <(printf '%s\n' "$inputC") | expand -t10

The best way I know of to do this the way you are wanting is messy. Even after that you may want to further refine the output to line up correctly.

share|improve this answer
    
This is pretty close to what I want. I'll tinker w/ it a bit. –  awreneau Jun 25 at 12:33
    
This formatting is nice but I could have up to 6 host in the Autostart and System columns and that would become unreadable. columnA="$inputA" columnB=$(echo "$inputB"|awk '{printf("%s,",$0)}'|sed 's/,.\s*$//') columnC=$(echo "$inputC"|tr '\n' ',') –  awreneau Jun 25 at 12:36
    
Actually, I was showing several ways to format it. Both all on one line and one per line are here. –  krowe Jun 25 at 21:31
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.