Как вывести содержимое массива в Столбцах в 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
Это может показаться излишним, но я придумал свое собственное решение. Я написал небольшой скрипт, который делает именно то, что я хотел: возьмите список значений и выведите их в довольно форматированном виде столбца.
Я знаю, что это старый поток, но я получаю неустойчивые результаты из столбца, поэтому я подумал, что дам свое решение. Я хотел сгруппировать каждые 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