我试图用空格将数组的所有项目填充到 20 个字符,但似乎无法让我的循环正常工作。它似乎正确地增加了数组项,但不会改变这些项。我这里哪里出错了?
#!/bin/bash
testArray=( "bish" "bash" "bosh")
padLine () {
array=( "${@}" )
testLength=20
counter=0
##loop begins here##
for i in "${array[@]}";
do
size=${#array[$counter]}
testLength=20
#echo ""
#echo "size: " $size
#echo "Tlength: " $testLength
#echo "count: " ${array[$counter]}
#echo ""
if [ $size -lt $testLength ]
then
offset=$( expr $testLength - $size )
#echo "Offset: " $offset
case $offset in
0)
l0=""
;;
1)
l1=" "
array[$counter]=${array[$counter]/%/$l1};;
2)
l2=" "
array[$counter]="${array[$counter]/%/$l2}";;
3)
l3=" "
array[$counter]=${array[$counter]/%/$l3};;
4)
l4=" "
array[$counter]="${array[$counter]/%/$l4}";;
5)
l5=" "
array[$counter]="${array[$counter]/%/$l5}";;
6)
l6=" "
array[$counter]=${array[$counter]/%/$l6};;
7)
l7=" "
array[$counter]=${array[$counter]/%/$l7};;
8)
l8=" "
array[$counter]=${array[$counter]/%/$l8};;
9)
l9=" "
array[$counter]=${array[$counter]/%/$l9};;
10)
l10=" "
array[$counter]=${array[$counter]/%/$l10};;
11)
l11=" "
array[$counter]=${array[$counter]/%/$l11};;
12)
l12=" "
array[$counter]=${array[$counter]/%/$l12};;
13)
l13=" "
array[$counter]=${array[$counter]/%/$l13};;
14)
l14=" "
array[$counter]=${array[$counter]/%/$l14};;
15)
l15=" "
array[$counter]=${array[$counter]/%/$l15};;
16)
l16=" "
array[$counter]=${array[$counter]/%/$l16};;
17)
l17=" "
array[$counter]=${array[$counter]/%/$l17};;
18)
l18=" "
array[$counter]=${array[$counter]/%/$l18};;
19)
l19=" "
array[$counter]=${array[$counter]/%/$l19};;
*)
esac
fi
counter=$( expr $counter + 1 )
done
}
padLine "${testArray[@]}"
echo -e "${testArray[0]}"
echo -e "${testArray[1]}"
echo -e "${testArray[2]}"
预期输出:
bish #lines end here, padded to 20 chars
bash #
bosh #
实际输出:
bish# no padding
bash
bosh
答案1
仅用于输出:
array=( bish bash bosh )
printf '%-20s#\n' "${array[@]}"
这会产生
bish #
bash #
bosh #
...#
出现在第 21 列中。
要创建一个新数组(并打印它):
array=( bish bash bosh )
for elem in "${array[@]}"; do
padarr+=( "$( printf '%-20s#' "$elem" )" )
done
printf '%s\n' "${padarr[@]}"
使用/bin/sh
,只需打印:
set -- bish bash bosh
printf '%-20s#\n' "$@"
使用/bin/sh
,$@
就地修改:
set -- bish bash bosh
i=0
while [ "$i" -lt "$#" ]; do
set -- "$@" "$( printf '%-20s#' "$1" )"
shift
i=$(( i + 1 ))
done
printf '%s\n' "$@"
格式化printf
字符串%-20s
为左对齐字符串保留 20 个字符。
作为bash
(4.3+) 函数:
pad_array () {
local padlen=$1
local -n localarray=$2
local -a tmp
local elem
for elem in "${localarray[@]}"; do
tmp+=( "$( printf '%-*s#' "$padlen" "$elem" )" )
done
localarray=( "${tmp[@]}" )
}
myarray=( bish bash bosh )
pad_array 20 myarray
printf '%s\n' "${myarray[@]}"
这里的功能pad_array
还允许您选择填充量。
该数组通过其名称传递,并由函数在名称引用变量中接收。这意味着每当在函数中访问名称引用时,实际上都会使用命名变量。
答案2
如果可以选择切换到zsh
:
$ array=(foo bar bàz '')
$ padded_array=(${(r:20:)array})
$ printf '<%s>\n' $padded_array
<foo >
<bar >
<bàz >
< >
请注意,(r:20:)
右填充参数扩展标志会填充,但对于较长的字符串也会截断为 20 个字符。
另一种选择zsh
是:
padded_array=()
(($#array)) && printf -v padded_array '%-20s' "$array[@]"
与 相反bash
,填充是按字符而不是按字节完成的,并且zsh
支持选项的数组参数-v
。
请注意,如果$array
仅包含一个元素,$padded_array
则转换为标量。
对于填充+截断,替换%-20s
为%-20.20s
.
答案3
你犯了两个错误。
您传递
testArray
给函数,然后在函数中创建新数组,修改它,但最终打印出第一个数组。您想打印修改后的结果,对吗?您的脚本没有执行您期望的操作,因为您使用了以下构造:
array[$counter]=${array[$counter]/%/$l16}
这就是一般形式的模式替代
${parameter/pattern/string}
。你不需要替代任何东西。此时您已准备好后缀,只需将其附加即可,如下所示:array[$counter]="${array[$counter]}${l16}"
您可以在函数外部访问该数组array
,因为该数组未声明为本地数组。所以你可以使用:
echo -e "${array[0]}"
ETC。
答案4
如果您愿意对要添加的空格数设置任意上限(显然您是这样做的,因为您的case
语句无法处理大于 20 的长度),并且您只是在谈论字节(而不是人物,可以是多字节),将变量填充到给定长度的简单方法是:
# 75 spaces
spaces=" "
︙
length=20
︙
newValue=$(expr substr "$value$spaces" 1 "$length")