在Bash中,从破折号字符开始绘制一个横线,该横线占据终端的全部宽度。

30

我需要一个在终端中画出横线的命令。这条线必须恰好与终端宽度一致(不考虑当前终端宽度),由连字符组成(尽管横线的Unicode符号也可以使用)。

最好能够给它加上颜色。

我需要像这样使用它:

echo some text
drawline
echo more text

输出结果可能类似于此:

echo some text
---------------------------------------------------------------------------------
echo more text

2
http://wiki.bash-hackers.org/snipplets/print_horizontal_line#a_line_across_the_entire_width_of_the_terminal - Inian
对于zsh:https://superuser.com/questions/845744/how-to-draw-a-line-between-commands-in-zsh-shell - Rufus
6个回答

34

尝试使用:

echo some text
printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' -
echo some text

29
没有署名?(原文意为在代码中没有任何提及作者的信息) - Benjamin W.
4
可以有人解释一下这是怎么工作的吗?我想把它缩短n个字符。 - Warpling

22
在 bash 和 zsh 中,有一个名为 $COLUMNS 的变量可供使用。
我使用以下命令来实现此目的:
printf %"$COLUMNS"s |tr " " "-"

您也可以使用seq,但这不如另一种解决方案直观:

seq -s- $COLUMNS|tr -d '[:digit:]'

编辑:

看起来$COLUMNS是一个本地的bash变量,你需要导出它。现在有(至少)两个选项。

  1. 在调用脚本之前导出变量:

    export COLUMNS; ./your_script.sh
    
  2. Zumo de Vidrio建议使用tput

  3. printf %"$(tput cols)"s |tr " " "-"
    

问题在于它在命令行上可以运行,但在脚本中却不能。 - exebook
1
好的,看起来我导出了“COLUMNS”,所以它才能正常工作。你可以采用相同的方法或使用@Zumo de Vidrio和我的解决方案的组合。我已经更新了我的答案。 - cb0

15

我将对当前最佳答案进行细节补充。您可以使用以下"hack"(也建议参考这里):

printf '%.s─' $(seq 1 $(tput cols))

注意这里不使用简单的短横线-,而是使用方框绘图中的横线。这样连续的短横线会连接在一起,打印出漂亮的连续线:

This nice line   ────────────────────────────
And not this one ----------------------------

例如,您可以使用此方法在每次注册使用zsh的钩子时显示一条线。

# ~/.zshrc
draw_hline=false
preexec() {
  if [[ $1 == ls* ]]; then
    hline
    draw_hline=true
  fi
}

precmd() {
  if [ $draw_hline = true ]; then
    hline
    echo
  fi
  draw_hline=false
}

使用bash注册挂钩可能可以通过这个非常类似的方式来完成。


在Bash中,花括号扩展发生在命令替换之前,所以你只会得到单个的-。要了解原因,请执行set -x; echo {1..$(tput cols)}; set +x,然后你会看到echo 命令为+ echo '{1..80}'而不是数字 1 到 80。你可以通过执行 eval printf '%.s-' \{1..$(tput cols)} 来改变评估顺序,并且你需要将 - 移动到 %.s 之后,以避免printf 将其视为选项标志。但是,你可以更简单地通过使用printf '%.s-' $(seq 1 $(tput cols))来获得所需的结果,而不使用花括号扩展。 - Steve Amerige
奇怪的是,无论是 set -x; echo $(seq 1 $(tput cols)); set +x 还是 set -x; echo {1..$(tput cols)}; set +x 在我的机器上都产生了完全相同的输出。两者都输出 echo 1 2 3 … 120 \n 1 2 3 … 120。也许 zsh 的函数方式不同,我会更新以在各种 shell 中实现更稳定的版本。谢谢。 - cglacet

4

一个简单的Perl one-liner
stty size | perl -ale 'print "-"x$F[1]'


注意
你可以通过stty size命令查看终端的高度宽度


enter image description here


很好。为了澄清:它会打印“-” $F[1] 次数。$F[1]stty size 命令输出的第二个值(由空格分隔),例如 57 228。我认为 print('string'x$number) 是一个很棒的 [tag:perl] 结构。 - user4104817
@w17t感谢您的反馈。我不确定是否理解您的意思。也许您想这样使用它:perl -le 'print "-" x qx(stty size | grep -o ...\$)',不需要使用分隔符和@F数组中的-a - Shakiba Moshiri

2

您可以使用tput设置颜色,使用printf根据列数打印行。

export RED=$(tput setaf 1 :-"" 2>/dev/null)
export GREEN=$(tput setaf 2 :-"" 2>/dev/null)
export YELLOW=$(tput setaf 3 :-"" 2>/dev/null)
export BLUE=$(tput setaf 4 :-"" 2>/dev/null)
export RESET=$(tput sgr0 :-"" 2>/dev/null)

echo $GREEN some text $RESET
echo $RED; printf -- "-%.0s" $(seq $(tput cols)); echo $RESET
echo $YELLOW more text $RESET

enter image description here


-1
超级简单的水平标尺:

repeat $(tput cols) echo -ne "-";


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接