我当前的代码如下所示:x=${y:0:40}
,它将字符串的长度限制为 40 个字符。如果字符串少于 40 个字符,是否可以用空格填充尾随位置?
所以如果我的y="very short text"
我希望我的y
成为:
y="非常短的文本(+25 个尾随空格)”
答案1
你应该试试printf
:
printf '%-40s' "$y"
答案2
如果这些字符都是单字节的,也就是说,如果您所在的语言环境的字符集是单字节的(如 iso8859-1),或者语言环境的字符集是 UTF-8 但文本仅为 ASCII,您可以这样做:
printf -v y %-40.40s "$y"
这将涵盖截断和填充。
如果没有,您可以随时添加 40 个空格并使用您的${y:0:40}
方法。
printf -v pad %40s
y=$y$pad
y=${y:0:40}
zsh
有专用的左右填充运算符:
y=${(r:40:)y}
(也进行截断)。zsh
的printf
计数以字符而不是字节为单位(或者如果还使用参数扩展标志,则基于字符的显示宽度m
),因此不会出现bash
上面的问题。但请注意,您需要zsh
5.3 或更高版本才能使用该-v
选项。
也可以看看这个相关问题的答案如果您遇到的字符宽度不一样,请了解更多详细信息。
答案3
纯的bash
:
ten=" "
forty="$ten$ten$ten$ten"
y="very short text"
y="${y:0:40}${forty:0:$((40 - ${#y}))}"
echo "'${y}'"
方法是对每个字符串截断后添加0-40个空格。
输出(注意单引号位置):
'very short text '
答案4
通常的使用建议printf
是错误的,它计算的是字节,而不是字符。即使它正确地(大多数时候)计算字符,
的使用也仅限于具有数组的 shell。${var:start:length}
更好的计数方法是基于${#var}
应该计算字符。
$ for var in 1 123 ΐΐΐ ᾂᾂ "㉑㉒㉓" aáéí;
> do
> printf '|%s%*s|\n' "$var" "$((10-${#var}))" "";
> done
|1 |
|123 |
|ΐΐΐ |
|ᾂᾂ |
|㉑㉒㉓ |
|aáéí |
但修剪字符串长度的唯一可移植方法是使用 grep。
#!/bin/sh
n=${1:-10}
for str in 1 123 123456789012 ΐ ΐΐΐ ΐΐΐΐΐΐΐΐΐΐ ΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐ ᾂᾂᾂᾂᾂ "㉑㉒㉓㉔㉕㉖㉗㉘㉙㉚" aáéíóúüñm
do
str=$str$(printf '%*s' "$n" "") # pad with `n` spaces.
var=$(echo "${str}"|grep -Eo "^.{1,$n}") # limit length to `n`
printf '|%s|\n' "${var}"
done
哪个打印:
|1 |
|123 |
|1234567890|
|ΐ |
|ΐΐΐ |
|ΐΐΐΐΐΐΐΐΐΐ|
|ΐΐΐΐΐΐΐΐΐΐ|
|ᾂᾂᾂᾂᾂ |
|㉑㉒㉓㉔㉕㉖㉗㉘㉙㉚|
|aáéíóúüñm |
请注意,四舍五入的数字是双倍宽度。仍然有 10 个字符,但它们占据了两倍的宽度。请注意,可以在某些 shell 中使用var=${str:0:n}
.
打印函数
printf 的实现通常仅限于计数字节(根据 POSIX 规范)。 ASCII 字符或其他每个字符一个字节的字符没有问题。但大多数其他国际人物都是这样做的:$ printf '|%-10.9s|..\n' 1234567890 ΐ U+0390 ᾂ U+1F82 "㉑㉒㉓㉔㉕㉖㉗㉘㉙㉚" aáéíóúüñm
|123456789 |..
|ΐ |..
|U+0390 |..
|ᾂ |..
|U+1F82 |..
|㉑㉒㉓ |..
|aáéíó |..
请注意,printf 应该在 10 个字符的空间中打印 9 个字符,格式如下%10.9s
。它确实这样做了1234567890
,它在 9 处剪切了数字,并在 10 个空格中打印出来|123456789 |..
。但ΐ
它在一个位置上失败,ᾂ
在两个位置上失败,㉑㉒㉓
在三个位置上失败,最后aáéíó
在四个位置上失败。
这里有两个不同的问题:
- 第一个是每个字符使用的字节数。例如,
㉑
need3
,这使得其中 3 个字符成为 9 个字节( printf 所需要的)。在这种情况下,printf 将 3 个字符计为 9 个字节。 - 第二个是每个字符的宽度。所有这些都
áéíóúüñ
需要两个字节,并且都是一个位置的宽度(与空格的宽度相同)。因此,printf
打印aáéíó
( 中的一个字节a
,其余的两个字节构成 9 个字节),仅 5 个字符,加上尾随空格,使总宽度为 6,短了 4 个空格。 - 打印时
㉑㉒㉓
每个字符需要 3 个字节,但每个字符使用 2 个空格的宽度,使得字符串显示时宽度为 6 个空格。