shell输出与终端宽度相同的重复字符

15次阅读

共计 1366 个字符,预计需要花费 4 分钟才能阅读完成。

来自我的笔记

我们有时候希望输出与当前终端宽度相等(或成正比)的重复字符,一般用作分隔、提示等,说白了就是好看或易于辨识一点点,例如使用 yum 安装软件时的那一排=,总是刚好排满一行,不会多不会少

Dependencies Resolved

===============================================================================
 Package              Arch           Version                  Repository  Size
===============================================================================
Reinstalling:
 vim-enhanced         x86_64         2:7.4.160-5.el7          os         1.0 M

Transaction Summary
===============================================================================
Reinstall  1 Package

这个功能的实现的两个重点:

  • 获取到当前终端的“宽度”
  • 重复输出刚好填满一行的字符

获取终端的“宽高”(列数和行数)

终端以单个字符为基本“单位”,终端中一行能输入多少个字符,该行就能划分成多少列(columns),也就是该行有多“宽”,“高度”亦同,即当前终端能划分成多少行(lines)。
我们可以使用以下方法获取终端的列数(宽)和行数(高):

  • $COLUMNSLINES 内置变量
  • tput colstput lines
  • stty size(输出两个数字,以空格分开,前面为行数 – 高,后面为列数 - 宽)

重复输出同一个字符串

这里我们以单个字符 = 为例,实现输出 10 个连续的 ===========
重复输出一个字符

  • 使用 printf

    s=$(printf "%-10s" "=")
    echo -e "${s// /=}"
    #或
    #sed "s/ /=/g"
    #printf "%-10s" "="|sed "s/ /=/g"

    prints 前面的 10 表示占用 10 个字符宽度,-表示左对齐(没有该符号表示右对齐),%s不必说,就是很多语言中的占位符号,s 表示 string 类型(不过把宽度 10 写到里面真是。。。)
    因此 print 语句就是占用 10 个字符的宽度,以 = 字符串填充,不过只有一个 = 因此实际上是 1 个 + 9 个空格占位=

再将 9 个空格替换成=

  • 使用 seq
    seq 作用是连续输出指定的数字,用法:

    seq [选项]… 尾数
    seq [选项]… 首数 尾数
    seq [选项]… 首数 增量 尾数

    默认的,seq 以 \n 为分隔符,每行输出一个数字,如果不指定首数,则首数为 1,如果不指定增量,则增量也为 1。

    seq 3  #这里只写了一个数字,则改数字就被当作尾数 也就是终止的数字

    输出

    1
    2
    3

     seq -s "=" 10|sed -E "s/[0-9]//g"
    1. seq 以 = 为分隔符生成与终端宽度字符数量相等的数字(形如1=2=3=4
    2. sed 正则匹配所有数字并替换为空字符串。

因此输出文章开头举例的那种一行 = 也就容易了:

# 使用 sed+print
printf "%-${COLUMNS}s" "="|sed "s/ /=/g"
#使用 seq+sed
 seq -s "=" ${COLUMNS}|sed -E "s/[0-9]//g"

正文完
 0