10

I am running a test multiple times on terminal and redirecting output to a file. While redirecting I want each run as a separate column. Currently, I am able to get the following:

Run1
1
2
3
4
Run2
1
2
3
4

How to redirect it as follow:

Run1  Run2
1      1
2      2
3      3
4      4
4
  • 3
    Take a look at the paste command. Commented Nov 13, 2017 at 19:56
  • This is unfortunately not trivially easy with core Unix tools. Possible duplicate: Bash: Split stdout from multiple concurrent commands into columns. Commented Nov 13, 2017 at 19:58
  • Thanks! Thought it will be easy but couldn't find anything. Commented Nov 13, 2017 at 20:02
  • n=5; paste <(sed -n 1,+$[$n-1]p file) <(sed -n $[1+$n],+$[$n-1]p file)? Commented Nov 13, 2017 at 20:31

3 Answers 3

13

With pr:

pr -2 -t -s file

or from stdin:

cat file | pr -2 -t -s

Output:

Run1    Run2
1       1
2       2
3       3
4       4

See: man pr

Sign up to request clarification or add additional context in comments.

Comments

0

If command1 produces Run1 and command2 produces Run2

paste <(command1) <(command2) | column -s $'\t' -tne

will join the outputs into columns.

Here is an example with silly commands

# paste <(ls -1 /var/log/*log) <(ls -1 /var/log/*/*_log) | column -s $'\t' -tne
/var/log/alternatives.log  /var/log/cups/access_log
/var/log/auth.log          /var/log/cups/error_log
/var/log/boot.log          /var/log/cups/page_log
/var/log/bootstrap.log     
/var/log/daemon.log        
/var/log/dpkg.log          
/var/log/faillog           
/var/log/fontconfig.log    
/var/log/kern.log          
/var/log/lastlog           
/var/log/pm-powersave.log  
/var/log/pm-suspend.log    
/var/log/pycentral.log     
/var/log/syslog            
/var/log/user.log          
/var/log/vbox-install.log  
/var/log/wvdialconf.log    
/var/log/Xorg.0.log        
/var/log/Xorg.1.log        
/var/log/Xorg.2.log  

Reference: https://sleeplessbeastie.eu/2018/11/19/how-to-display-output-of-multiple-commands-using-columns/

IF you want to display AND redirect to a file, each command could include a tee that does that.

It is always good idea to include your own commands (or dummy ones) so we can give you a more specific answer.

Comments

0

While the accepted solution with pr is quite elegant, it has a problem, similar to the one with paste: if the length of the different lines are bigger than 8 (the default size in spaces of a tab char), the output lines are displaced. The bigger the difference in length of the lines, the messier gets the output.

Unfortunately, I did not find a more robust way to do this than using a small awk script, that of course can be put in a separate file for reuse.

If you have a file like this (lipsum.txt):

$ cat lipsum.txt
Lorem ipsum dolor sit amet, 
consectetur adipiscing elit. 
Cras hendrerit scelerisque sollicitudin. 
In at mauris cursus, 
varius eros ut, 
dignissim urna. 
Nullam est orci, 
molestie sit amet risus in, 
commodo dignissim justo. 
Morbi eu enim leo. 
Proin pulvinar consectetur elit, 
in viverra nisl ultrices quis. 
Vivamus ac lacus eget urna auctor finibus. 
Suspendisse potenti. 
Vestibulum sed ligula nisl.

The accepted solution will result as follows:

$ cat lipsum.txt | pr -2 -t -s
Lorem ipsum dolor sit amet,     commodo dignissim justo.
consectetur adipiscing elit.    Morbi eu enim leo.
Cras hendrerit scelerisque sollicitudin.    Proin pulvinar consectetur elit,
In at mauris cursus,    in viverra nisl ultrices quis.
varius eros ut,     Vivamus ac lacus eget urna auctor finibus.
dignissim urna.     Suspendisse potenti.
Nullam est orci,    Vestibulum sed ligula nisl.
molestie sit amet risus in,     

With the following (long) oneliner, you save in an array all the lines while measuring their length, and then shows them again in two columns, with the appropriate width (set to the max. length of the lines).

$ cat lipsum.txt |awk 'BEGIN{w=0;}{lines[NR]=$0;l=length($0);w=l>w?l:w;}END{wd=W>0?W:w;h=rshift(NR,1)+(NR%2);for (i=1;i<=h;i++){printf "%*s %s %*s\n",-wd,lines[i],sep,-wd,lines[i+h];}}'
Lorem ipsum dolor sit amet,                  commodo dignissim justo.                   
consectetur adipiscing elit.                 Morbi eu enim leo.                         
Cras hendrerit scelerisque sollicitudin.     Proin pulvinar consectetur elit,           
In at mauris cursus,                         in viverra nisl ultrices quis.             
varius eros ut,                              Vivamus ac lacus eget urna auctor finibus. 
dignissim urna.                              Suspendisse potenti.                       
Nullam est orci,                             Vestibulum sed ligula nisl.                
molestie sit amet risus in,       

You can even set the string separator with the variable sep and the width of the column with the variable W (if it is smaller than the max. line length, you will get effects similar to those with paste or pr, of course):

$ cat lipsum.txt |awk -v W=50 -v sep='|:|' 'BEGIN{w=0;}{lines[NR]=$0;l=length($0);w=l>w?l:w;}END{wd=W>0?W:w;h=rshift(NR,1)+(NR%2);for (i=1;i<=h;i++){printf "%*s %s %*s\n",-wd,lines[i],sep,-wd,lines[i+h];}}'
Lorem ipsum dolor sit amet,                        |:| commodo dignissim justo.                          
consectetur adipiscing elit.                       |:| Morbi eu enim leo.                                
Cras hendrerit scelerisque sollicitudin.           |:| Proin pulvinar consectetur elit,                  
In at mauris cursus,                               |:| in viverra nisl ultrices quis.                    
varius eros ut,                                    |:| Vivamus ac lacus eget urna auctor finibus.        
dignissim urna.                                    |:| Suspendisse potenti.                              
Nullam est orci,                                   |:| Vestibulum sed ligula nisl.                       
molestie sit amet risus in,                        |:|      

3 Comments

awk: line 2: function rshift never defined $ awk -W version mawk 1.3.4 20200120 ... Package awk is a virtual package provided by: original-awk 2018-08-27-1 mawk:i386 1.3.4.20200120-3.1 gawk:i386 1:5.1.0-1build3 mawk 1.3.4.20200120-3.1 gawk 1:5.1.0-1build3
Yep, @avp, you are right, in some AWK versions the rshift() is not implemented. You can always create your own right shift function in AWK, like this very simplistic one: function r_shift (num, nb) { for (i=0; i<nb; i++){num=int(num/2);} return(num);}. In this case, placing the AWK code in a stand-alone script seems preferable.
you can actually roughly do this with -W which is "always width". So a -W 90, for instance will make sure each column is always 90 characters. This may truncate longer output, but at least it's not a giant mess.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.