Как вывести содержимое массива в Столбцах в BASH

Я хотел отобразить длинный список строк из массива.

прямо сейчас мой скрипт проходит через цикл for, повторяющий каждое значение для стандартного вывода:

for value in ${values[@]}
do
  echo $value
done

Да, это очень некрасиво! И список в одной колонке тоже довольно длинный...

мне было интересно, могу ли я найти команду или встроенный, помогающий мне отображать все эти значения в Столбцах, например ls команда делает по умолчанию при перечислении каталога (ls -C).

[обновление]

потерять свой мозг с column не отображается должным образом отформатированные столбцы, вот дополнительная информация:

значения: $ values=( 01----7 02----7 03-----8 04----7 05-----8 06-----8 07-----8 08-----8 09---6 10----7 11----7 12----7 13----7 14-----8 15-----8 16----7 17----7 18---6 19-----8 20-----8 21-----8) (обратите внимание на первые две цифры в качестве индекса и последнюю, указывающую длину строки для удобства чтения)

команды: echo " ${values[@]/%/$'n'}" | column

результат: плохие колонки http://tychostudios.ch/multipurpose/bad_columns.png

что-то идет не так...

7 ответов


вы можете передать свой вывод в column.

column Кажется, борется с некоторыми данными в одноколоночном входе, более узком, чем tabstop (8 символов).

используя printf внутри for-цикл для заполнения значений до 8 символов, похоже, делает трюк:

for value in "${values[@]}"; do 
    printf "%-8s\n" "${value}"
done | column

вот несколько методов, которые можно использовать с Johnsyweb это ответ таким образом, вы можете сделать свой вывод без цикла:

saveIFS=$IFS
IFS=$'\n'
echo "${values[*]}" | column
IFS=$saveIFS

или

echo " ${arr[@]/%/$'\n'}" | column

или

echo " ${arr[@]/%/$'\n'}" | sed 's/^ //' | column

Это может показаться излишним, но я придумал свое собственное решение. Я написал небольшой скрипт, который делает именно то, что я хотел: возьмите список значений и выведите их в довольно форматированном виде столбца.

http://github.com/Arko/Columnize


Я знаю, что это старый поток, но я получаю неустойчивые результаты из столбца, поэтому я подумал, что дам свое решение. Я хотел сгруппировать каждые 3 строки в 3 равномерно расположенных столбца.

cat file.txt | xargs printf '%-24s\n' | sed '$p;N;s/\n//;$p;N;s/\n//'

в основном, он передает каждую строку в printf, который выравнивает ее по левому краю в 24-символьный блок пробелов, который затем передается в sed. sed будет смотреть вперед 2 линии в будущее и удалить разрыв линии.

команда N считывает следующую строку в текущий буфер и s/\n/ / удаляет разрыв строки. Короче говоря, мы хотим 'N;N;s/\n//g', который будет работать в некоторых случаях. Проблема в том, что если нет двух дополнительных строк для броска в буфер, sed внезапно прекратит работу. Команды $p предупреждают это, говоря:"если это последняя строка, немедленно распечатайте содержимое буфера".


Я знаю, что это старая нить, но я столкнулся с той же ситуацией. В итоге я объединил несколько идей.

для решения на основе утилиты столбца (без начальной проблемы с пространством):

(IFS=''; echo "${values[*]/%/$'\n'}") | column

используя скрипт @Arko для basis, это может обрабатывать значения с пробелами. Обратите внимание на функции printf спецификация %-*s по левому краю колонки и ладно бы падение '-'. Я не включил свой терминал, но он настроен (terminalWidth).

#  e.g.  column "$@"
#        spacing=4 column "$@"
#        left=6 spacing=3 column "$@"
#
function column() {
    local leftMargin=${left:-0}
    local padding=${spacing:-2}
    local maxWidth=$(( ${terminalWidth:-80} - $leftMargin ))
    local values=("$@")
    local max=$(( $(IFS=''; echo "${values[*]/%/$'\n'}" | wc -L) + $padding ))
    local cols=$(( $maxWidth / $max ))

    local pos=0 NL=''
    for value in "${values[@]}"; do
        [[ $pos == 0 ]] && {
            printf "$NL%*s" "$leftMargin"
            NL=$'\n'  # add newlines from now on...
        }
        printf "%-*s" "$max" "$value"
        (( pos = ($pos + 1) % $cols ))
    done
    echo

}


почему-то column не работает для меня. В моем случае у меня есть массив типа

$ array = ( 1 2 3 dir1 dir2 dir3 )
$
$ echo ${array[@]} | column            
1 2 3 dir1 dir2 dir3
Я
$ echo ${array[@]} | tr ' ' '\n' | sort
1
2
3
dir1
dir2
dir3

Tabspaces


используйте вкладку после каждого значения.

(он автоматически перетекает в следующую строку... )

for value in ${values[@]}
do
  echo -en "$value\t"
done

подробная информация здесь

удачи!!
- CVS