在纳米文本编辑器中,我可以将选择传输到命令中,并且我经常需要将文本居中,所以我想出了以下代码
center() {
str=$1
# Strip leading and trailing whitespace from the string
str=$(echo "$str" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
str_len=${#str}
margin=$(((80 - str_len) / 2))
printf "%*s%s%*s\n" $margin "" "$str" $margin ""
}
但我对脚本了解不多,所以我想知道如何改进这段代码。
为什么要链接到 bash 解决方案?我不使用这个 shell,我只是想让它与 sh 一起运行
答案1
假设您正在使用bash
shell(如果不使用,请参阅此答案的末尾),您可以使用标准变量扩展和扩展通配模式(匹配一个或多个类似空格的字符)更有效地bash
从字符串中去除侧翼空格:str
+([[:space:]])
shopt -s extglob
str=$1
str=${str##+([[:space:]])} # strip at start
str=${str%%+([[:space:]])} # strip at end
我们想要打印右对齐到 ( 给出的列w+s)/2,其中w是终端的宽度(由 输出tput cols
,但您也可以使用$COLUMNS
)并且s是字符串 ( ${#str}
) 的长度:
printf '%*s\n' "$(( ( $(tput cols) + ${#str} ) / 2 ))" "$str"
功能:
center () (
shopt -s extglob
str=$1
str=${str##+([[:space:]])}
str=${str%%+([[:space:]])}
printf '%*s\n' "$(( ( $(tput cols) + ${#str} ) / 2 ))" "$str"
)
请注意,函数的主体是一个子 shell。这样extglob
shell 选项的设置就不会溢出到调用 shell 中。
不依赖extglob
(适用于任何sh
):
center () {
str=$(printf '%s\n' "$1" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
printf '%*s\n' "$(( ( $(tput cols) + ${#str} ) / 2 ))" "$str"
}
如果要将其格式设置为静态 80 列宽度,请替换$(tput cols)
为。80
答案2
如果中间没有连接多个空格,则可以使用以下命令简化修剪str=$(echo $1)
center () {
str=$(echo $1)
len=${#str}
margin=$((($COLUMNS - len) / 2))
printf "%${margin}s%s\n" " " "$str"
}
您不需要在 后面添加空格$str
。