0

The following script outputs a numbered list of items.

#!/bin/bash

menu=( $(ls ${HOME}) )
i=0
for m in ${menu[@]}
do 
    echo  "$(( i++ ))) $m"
done

The result:

0) item
1) item
2) item
3) item

I would like to split that list into multiple columns so more data fits on one page. Simply piping to column echo "$(( i++ ))) $m" | column still results in a single column only now every line begins with 0) followed by the item listed.

The answers given in How to output an array's content in columns in BASH work as far as making multiple columns of output.

menu=( $(ls $HOME) )
echo " ${menu[@]/%/$'\n'}" | column

But because the array is quoted, using the bash arithmetic method i=0; echo "$(( i++ ))" doesn't work for numbering as the only number output is the first 0.

My question is: How can I output the data from an array into an numbered list of multiple columns?

0) item        4) item        8) item
1) item        5) item        9) item
2) item        6) item       10) item
3) item        7) item       11) item
2
  • Your code has multiple issues when it comes to filenames containing whitespace or shell metacharacters. Don't use ls and quote everything. Anyway looks like you are actually looking simply for select file in "$HOME"/* Commented Sep 15, 2016 at 11:18
  • I know you are correct. In this particular example though I am certain that none of the filenames contain any whitespace or metacharacters. Commented Sep 15, 2016 at 11:36

2 Answers 2

3

How about you print it out single column and pipe it to pr:

$ for i in {0..11}; do echo $i ; done|pr -ts" " --columns 3
0 4 8
1 5 9
2 6 10
3 7 11
Sign up to request clarification or add additional context in comments.

10 Comments

Well, do you have a stray - in ps's parameters? What are you using... as an OS I mean?
I copied what is written verbatim for i in {0..11}; do echo $i ; done|pr -ts" " --columns 3. I am using Mac OS X.
I don't have a Mac available. Any Mac users who can man pr? --columns probably has an alias.
The man page shows an option for -column. "Produce output that is columns wide (default is 1) that is written vertically down each column in the order in which the text is received from the input file. The options -e and -i are assumed. This option should not be used with -m. When used with -t, the minimum number of lines is used to display the output." Still getting error "illegal option -- c"
Well, I would use -column 3instead of --columns 3 then.
|
2

Added few changes to your original script, now xargs and column -t will divide the line after every three records and then column -t will indentate it properly. Avoid using ls to get the file list.

#!/bin/bash

menu=( $HOME/* )
i=0
for m in ${menu[@]}
do
    echo  "$(( i++ ))) $(basename $m)"
done |xargs -L3 |column -t

Sample output:

0)   Desktop      1)   Documents  2)   Downloads
3)   Music        4)   Pictures   5)   Public
6)   Templates    7)   XXX        8)   Videos
9)   backup_XXXX  10)  dna        11)  scripting
12)  sessions     13)  sh         14)  temp

1 Comment

how can you do this where 0-4 are an the same column?

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.