How to print multiline variables in side-by-side columns in bash?
I have two variables which contain multi-line information and I want to column them.
varA
returns
Aug 01
Aug 04
Aug 16
Aug 26
and varB
returns
04:25
07:28
03:39
10:06
if i print both variables, it returns
Aug01
Aug04
Aug16
Aug26
04:25
07:28
03:39
10:06
What I want to do is the following:
Aug01 04:25
Aug04 07:28
Aug16 03:39
Aug26 10:06
I'm new to using Linux and I would appreciate some advice.
Solution 1:
Meet paste
, part of the preinstalled GNU core utilities:
$ paste <(printf %s "$varA") <(printf %s "$varB")
Aug 01 04:25
Aug 04 07:28
Aug 16 03:39
Aug 26 10:06
paste
takes files and not variables as input, so I used bash
Process Substitution and just printed the variable content with printf
. The default delimiter between columns is TAB
, you can change that with the -d
option, e.g. paste -d" "
for a single space character. To learn more about paste
have a look at the online manual or run info '(coreutils) paste invocation'
.
Solution 2:
If you just want to simply display the text variables side by side, @dessert has the most simple (best?) solution using print
. However if you want to be able to manipulate each piece individually, you could easily convert the vars to arrays instead, and loop through that.
#!/bin/bash
# declare the multi-line variables
var1="1
2
3
4"
var2="a
b
c
d"
# backup internal field separator to be safe
IFSave=$IFS
# set IFS to newline so vars will use newline to split into array
IFS=$'\n'
# split variables into array
foo=($var1)
bar=($var2)
#restore IFS to original value to be safe
IFS=$IFSave
# loop array foo, and cross reference key in array bar
for i in "${!foo[@]}"; do
printf "${foo[$i]} : ${bar[$i]}\n"
done
# you can allso now print single corresponding lines:
line=3
let id=$line-1 # arrays start at 0, so need to remove one
printf "\nPrinting line number $line\n"
printf "${foo[$id]} : ${bar[$id]}\n"
Solution 3:
You can do this with the POSIX tool pr
:
varA='Aug 01
Aug 04
Aug 16
Aug 26'
varB='04:25
07:28
03:39
10:06'
pr -2 -t <<eof
$varA
$varB
eof
Result:
Aug 01 04:25
Aug 04 07:28
Aug 16 03:39
Aug 26 10:06
Or for single tab:
pr -2 -t -s
Or for single space:
pr -2 -t -s' '
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pr.html
Or with column
from the util-linux
package:
column -c 20 <<eof
$varA
$varB
eof