Reputation: 900
I understand there are multiple ways to output pretty columns using while or for loops along with awk, echo, printf, etc. What I'm looking for is a simple intuitive way (not messy) to easily print columns using the column(1) command and two bash arrays.
I have found the following Q&A: How can I format the output of a bash command in neat columns
which states how to use column
very clearly, but the question asks about a bash command and gives a single command/string as its example.
My scenario is - I have two bash arrays (in_db
and local
). in_db[$i]
entries are Y
or N
if local[$i]
entries are in my mysql db. I would like to have the entries of in_db
array as the first column and entries of local
array as the 2nd column. Both columns will have the same number of entries/rows. I don't want to print any output to files.
I have tried:
column -x -s "**" -t <<< (echo ${in_db[@]}; echo ${local[@]})
where the entries in in_db
will have a **
at the end of the string to delimit the end of that 1st column. My assumption of the -x flag in column
is that it will print all in_db
entries first in the first column (hence why I print in_db first). I understand that the above column
command does not print to my liking and I'm obviously missing the explaination of description for the -x
flag. I'm trying different scenarios and -flags to make it print correctly.
I have also tried, instead of using two separate arrays, to prepend the local
array with the string from in_db
in a loop:
i=0
local_count=${#local[@]}
while [ $i -lt $local_count ]; do
q=$(mysql --defaults-extra-file="/tmp/my.cnf" mp3s \
-e "select folder_location from folders where folder_location = \"${local[$i]}/\"" -s -N)
if [[ -z $q ]]; then
local[$i]="N**${local[$i]}"
else local[$i]="Y**${local[$i]}"
fi
i=$((i+1))
done
echo ${local[@]} | column -s "**" -t
This prints as one line:
N music/atmosphere-sad_clown_bad_dub_13-(rse0095)-bonus_dvd-2008-raceme N music/blink-182 - California (2016) [V0] N music/Vitalogy N music/Pearl Jam - Ten (1991) [V0] N music/Vs N music/Pearl Jam - No Code N music/Pearl Jam - Riot Act N music/Pearl Jam - Transmission Impossible (Live) (2015) [MP3] N music/Pearl Jam N music/Binaural N music/Yield N music/Pearl Jam ~ Backspacer [V0]-2009 Y music/Beastie Boys - The In Sound From Way Out! (V0) N music/Beastie Boys - Licensed To Ill N music/Paul's Boutique 20th Anniversary Remastered Edition [V0] Y music/1992 - Check Your Head Y music/Beastie Boys - Ill Communication N music/Beastie Boys - Hello Nasty N music/Beastie Boys - (2004) - To The 5 Boroughs [V0] N music/Beastie Boys - The Mix-Up (2007) N music/Highway 61 Revisited V0 Y music/1997 - Live Between Us [V0] N music/2006 - World Container [V0] N music/The Tragically Hip - 2012 - Now For Plan A (MP3 V0) Y music/Red Hot Chili Peppers - The Getaway (2016) [V0]
Any ideas?
Upvotes: 0
Views: 1233
Reputation: 113924
Suppose that we have two arrays. For example:
in_db=(Y N Y N)
local=(one two three four)
To print them out neatly in two columns:
$ paste <(printf "%s\n" "${local[@]}") <(printf "%s\n" "${in_db[@]}")
one Y
two N
three Y
four N
As you can see, column
is not really needed but we can use it if you like:
$ paste <(printf "%s\n" "${local[@]}") <(printf "%s\n" "${in_db[@]}") | column -t
one Y
two N
three Y
four N
paste
allows us to combine two or more files a line at a time. By default, the lines are combined with tabs as the separator.
Since you want to combine arrays, not files, we have to convert the arrays into file-like objects. We do that using bash's process substitution feature. In bash, <(...)
creates a file-like object. The contents of the "file" are whatever the output is of the commands inside the parens. In this case, we use printf
to format each of the arrays as one item per line.
Upvotes: 4