右对齐空白列(bash)?

时间:2019-03-06 01:21:33

标签: arrays bash shell

我有一个打印列的脚本,但是如果左列为空,它将无法正确对齐。

现在,我正在遍历数组并打印键/值,并使用column命令格式化列。下面是代码的样子。

# Code to make the array
declare -A pods
declare -A associative_array
pods=$(kubectl get pods | awk '{if(NR>1)print $1}')
for p in ${pods[*]}; do
    image=$(kubectl get pod "$p" -o json | jq -r '.spec.containers[].image')
    associative_array[$p]+="$image"
done

# Code to print the array
(printf "column1\tcolumn2\n"

for i in "${!associative_array[@]}"; do
    printf '%s\t%s\n' "$i" "${associative_array[$i]}"
done) | column -t -x
...

这是当前输出的示例。

column1                                           column2
prometheus-k8s-0                                  carlosedp/prometheus:v2.7.1
carlosedp/prometheus-config-reloader:v0.28.0
carlosedp/configmap-reload:v0.2.2

如果第一列为空,是否有一种简单的方法可以使文本正确对齐?

更新

我发现了问题之一,并更新了代码以显示如何创建阵列。我用来创建第一个数组的命令是添加换行符。

在更新以删除换行符之后,输出现在看起来像这样,因此在任何情况下都不存在空键,只是在某些情况下给定键具有多个值。

column1                               column2
prometheus-k8s-0                      carlosedp/prometheus:v2.7.1 carlosedp/prometheus-config-reloader:v0.28.0 carlosedp/configmap-reload:v0.2.2

3 个答案:

答案 0 :(得分:2)

看起来您只需要在%s调用的第一个printf中添加长度说明符即可:

$ printf "%-50s%s\n" "$i" "${associative_array[$i]}"

请注意,这摆脱了制表符,不再需要使用制表符,因为第一列现在用空格右填充,直到其长度为50个字符为止。另外,我选择50是因为这是前两行中第1列的宽度。

如果使用这种方法,您还希望最后删除| column -t -x,因为它现在是多余的,并且实际上会撤消printf的格式,因为它将连续的定界符视为单个定界符。

如果您的column版本支持它,则也可以尝试保持printf不变,而改用column -t -x -s $'\t' -n,它告诉column使用{{1 }}作为定界符,并且不将多个相邻定界符视为单个定界符:

\t

当然,您可以分组一些选项并缩短

$ printf "%s\t%s\n" column1 column2 foo bar "" baz | column -t -x -s $'\t' -n
column1  column2
foo      bar
         baz

column -t -x -s $'\n' -n

答案 1 :(得分:2)

You certainly don't work with an associative array.
You can't assign a emty key.
Try that and see what happen !

declare -A associative_array=( [one]=bar []=truc [three]=foo [four]=baz)
(printf "column1\tcolumn2\n"
for i in "${!associative_array[@]}"; do
  printf '%s\t%s\n' "$i" "${associative_array[$i]}"
done)
echo "number of items = ${#associative_array[@]}"

./script-bash.sh: line 1: []=truc: bad array subscript
column1 column2
four    baz
three   foo
one     bar
number of items = 3

答案 2 :(得分:0)

这不是一个完美的解决方案,但是我可以通过检查第二列是否有多个单词,然后将其拆分并在每个字符串上进行迭代来大致了解我想要的行为。

for i in "${!associative_array[@]}"; do
    if [[ $(echo "${associative_array[$i]}" | wc -w) -gt 1 ]]; then
        for image in ${associative_array[$i]}; do
            printf '%s\t%s\n' "$i" "$image"
        done
    else
        printf '%s\t%s\n' "$i" "${associative_array[$i]}"
    fi
done) | column -t -x

将产生以下输出。

prometheus-k8s-0                      carlosedp/prometheus:v2.7.1
prometheus-k8s-0                      carlosedp/prometheus-config-reloader:v0.28.0
prometheus-k8s-0                      carlosedp/configmap-reload:v0.2.2