Home > OS >  Print every few lines as a column
Print every few lines as a column

Time:10-28

I have a script that gets information about servers and stores it in a variable.

➜ echo $report
 Hostname : or-05-arm
 CheckDate: 11:47 27-10-2022
 CPU Usage: [..........] 0%  [0.00/2]
 RAM Usage: [###.......] 31% [1.8G/5.8G]
 HDD Avail: 26G
 Uptime   : up 19 weeks

 Hostname : contabo-3
 CheckDate: 14:47 27-10-2022
 CPU Usage: [#####.....] 50% [3.01/6]
 RAM Usage: [###.......] 30% [4.7G/15.6G]
 HDD Avail: 136G
 Uptime   : up 1 week

 Hostname : contabo-2
 CheckDate: 14:47 27-10-2022
 CPU Usage: [#####.....] 53% [3.16/6]
 RAM Usage: [##........] 25% [3.9G/15.6G]
 HDD Avail: 176G
 Uptime   : up 1 week

Using awk and a column, I display the contents of the report variable on the screen in three columns.

➜ echo $report | awk '{a[NR%7] = a[NR%7] (NR<=7 ? "" : ",") $0} END{for (i = 1; i <= 7; i  ) print a[i%7]}' | column -t -s ','

 Hostname : or-05-arm                      Hostname : contabo-3                       Hostname : contabo-2
 CheckDate: 11:47 27-10-2022               CheckDate: 14:47 27-10-2022                CheckDate: 14:47 27-10-2022
 CPU Usage: [..........] 0%  [0.00/2]      CPU Usage: [#####.....] 50% [3.01/6]       CPU Usage: [#####.....] 53% [3.16/6]
 RAM Usage: [###.......] 31% [1.8G/5.8G]   RAM Usage: [###.......] 30% [4.7G/15.6G]   RAM Usage: [##........] 25% [3.9G/15.6G]
 HDD Avail: 26G                            HDD Avail: 136G                            HDD Avail: 176G
 Uptime   : up 19 weeks                    Uptime   : up 1 week                       Uptime   : up 1 week

This works as long as no more than three servers are stored in the variable. If there are more than three servers, then the output does not fit on the screen.

How to make 3 servers appear on the screen, then three more on the next line, and so on?

CodePudding user response:

You can use fold to break the output into lines of a given length.

echo $report | awk '{a[NR%7] = a[NR%7] (NR<=7 ? "" : ",") $0} END{for (i = 1; i <= 7; i  ) print a[i%7]}' | column -t -s ',' | fold -w 80

CodePudding user response:

Assumptions:

  • each block of text contains exactly 6 lines (not counting blank lines)
  • the last line of each block of text includes the string Uptime
  • Uptime does not show up in any other lines

Setup (7 blocks of data):

$ cat report.dat
 Hostname : or-05-arm
 CheckDate: 11:47 27-10-2022
 CPU Usage: [..........] 0%  [0.00/2]
 RAM Usage: [###.......] 31% [1.8G/5.8G]
 HDD Avail: 26G
 Uptime   : up 19 weeks

 Hostname : contabo-3
 CheckDate: 14:47 27-10-2022
 CPU Usage: [#####.....] 50% [3.01/6]
 RAM Usage: [###.......] 30% [4.7G/15.6G]
 HDD Avail: 136G
 Uptime   : up 1 week

 Hostname : contabo-2
 CheckDate: 14:47 27-10-2022
 CPU Usage: [#####.....] 53% [3.16/6]
 RAM Usage: [##........] 25% [3.9G/15.6G]
 HDD Avail: 176G
 Uptime   : up 1 week

 Hostname : or-05-arm
 CheckDate: 11:47 27-10-2022
 CPU Usage: [..........] 0%  [0.00/2]
 RAM Usage: [###.......] 31% [1.8G/5.8G]
 HDD Avail: 26G
 Uptime   : up 19 weeks

 Hostname : contabo-3
 CheckDate: 14:47 27-10-2022
 CPU Usage: [#####.....] 50% [3.01/6]
 RAM Usage: [###.......] 30% [4.7G/15.6G]
 HDD Avail: 136G
 Uptime   : up 1 week

 Hostname : contabo-2
 CheckDate: 14:47 27-10-2022
 CPU Usage: [#####.....] 53% [3.16/6]
 RAM Usage: [##........] 25% [3.9G/15.6G]
 HDD Avail: 176G
 Uptime   : up 1 week

 Hostname : or-05-arm
 CheckDate: 11:47 27-10-2022
 CPU Usage: [..........] 0%  [0.00/2]
 RAM Usage: [###.......] 31% [1.8G/5.8G]
 HDD Avail: 26G
 Uptime   : up 19 weeks

Adding a couple counters and a function (to print 3x blocks at a time) to OP's current awk code:

awk '

function print_block() {
    for (i = 1; i <= 7; i  )
        print a[i%7]
    print ","                           # column will convert this to a blank line
    delete a                            # clear array
    upcount=linecount=0                 # reset counters
}

! NF       { next }                     # skip blank lines
           { linecount   }
           { a[linecount % 7] = a[linecount % 7] (linecount <= 7 ? "" : ",") $0 }

/Uptime/   { upcount   }
upcount>=3 { print_block() }            # dump array to stdout for each 3rd occurrence of "Uptime"
END        { print_block() }            # flush anything still in array once all input has been processed

' report.dat | column -t -s,

This generates:

 Hostname : or-05-arm                      CheckDate: 14:47 27-10-2022                CPU Usage: [#####.....] 53% [3.16/6]
 CheckDate: 11:47 27-10-2022               CPU Usage: [#####.....] 50% [3.01/6]       RAM Usage: [##........] 25% [3.9G/15.6G]
 CPU Usage: [..........] 0%  [0.00/2]      RAM Usage: [###.......] 30% [4.7G/15.6G]   HDD Avail: 176G
 RAM Usage: [###.......] 31% [1.8G/5.8G]   HDD Avail: 136G                            Uptime   : up 1 week
 HDD Avail: 26G                            Uptime   : up 1 week
 Uptime   : up 19 weeks                    Hostname : contabo-2
 Hostname : contabo-3                      CheckDate: 14:47 27-10-2022

 Hostname : or-05-arm                      CheckDate: 14:47 27-10-2022                CPU Usage: [#####.....] 53% [3.16/6]
 CheckDate: 11:47 27-10-2022               CPU Usage: [#####.....] 50% [3.01/6]       RAM Usage: [##........] 25% [3.9G/15.6G]
 CPU Usage: [..........] 0%  [0.00/2]      RAM Usage: [###.......] 30% [4.7G/15.6G]   HDD Avail: 176G
 RAM Usage: [###.......] 31% [1.8G/5.8G]   HDD Avail: 136G                            Uptime   : up 1 week
 HDD Avail: 26G                            Uptime   : up 1 week
 Uptime   : up 19 weeks                    Hostname : contabo-2
 Hostname : contabo-3                      CheckDate: 14:47 27-10-2022

 Hostname : or-05-arm
 CheckDate: 11:47 27-10-2022
 CPU Usage: [..........] 0%  [0.00/2]
 RAM Usage: [###.......] 31% [1.8G/5.8G]
 HDD Avail: 26G
 Uptime   : up 19 weeks

If OP has pre-loaded all of the data into a variable then there a couple options:

echo "${report}" | awk '... see code from above ...'                 | column -t -s,

# or
                   awk '... see code from above ...' <<< "${report}" | column -t -s,

NOTE: ${report} must be wrapped in double quotes

  • Related