bash 控制台输出打印布局

bash console output print layout

我想让我的控制台输出以一种整洁的人类可读的方式写入。 这是现在的样子:

====================== Sat Apr 16 12:57:17 EDT 2022 ======================
==========================================================================
======================  Leopard - Download from S3  ======================
==========================================================================
==========================================================================
======================  Leopard - Decompressing  ======================
==========================================================================
total 1349872
drwxr-xr-x  2 root root     12288 Apr 16 12:57 .
drwxrwxrwt. 4 root root       102 Apr 16 12:57 ..
-rw-r--r--  1 root root 185070885 Apr 16 12:03 asdasdasd.sql.gz
-rw-r--r--  1 root root  40344632 Apr 16 12:03 asdasdas.sql.gz
-rw-r--r--  1 root root     26631 Apr 16 12:03 asdad.sql.gz
-rw-r--r--  1 root root      1679 Apr 16 12:03 asdasd.sql.gz
-rw-r--r--  1 root root      1237 Apr 16 12:03 asd.sql.gz
-rw-r--r--  1 root root   5241900 Apr 16 12:03 asdasd.sql.gz
-rw-r--r--  1 root root      1144 Apr 16 12:03 asdasasd.sql.gz
-rw-r--r--  1 root root    489312 Apr 16 12:03 asdasd.sql.gz
-rw-r--r--  1 root root      1138 Apr 16 12:03 asdasdasd.sql.gz
==========================================================================
======================  NewYorkCity - Download from S3  ======================
==========================================================================
==========================================================================
======================  NewYorkCity - Unloading SSL Example  ======================
==========================================================================
total 1349872
drwxr-xr-x  2 root root     12288 Apr 16 12:57 .
drwxrwxrwt. 4 root root       102 Apr 16 12:57 ..
-rw-r--r--  1 root root 185070885 Apr 16 12:03 asdasdasd.sql.gz
-rw-r--r--  1 root root  40344632 Apr 16 12:03 asdasdas.sql.gz
-rw-r--r--  1 root root     26631 Apr 16 12:03 asdad.sql.gz
-rw-r--r--  1 root root      1679 Apr 16 12:03 asdasd.sql.gz
-rw-r--r--  1 root root      1237 Apr 16 12:03 asd.sql.gz
-rw-r--r--  1 root root   5241900 Apr 16 12:03 asdasd.sql.gz
-rw-r--r--  1 root root      1144 Apr 16 12:03 asdasasd.sql.gz
-rw-r--r--  1 root root    489312 Apr 16 12:03 asdasd.sql.gz
-rw-r--r--  1 root root      1138 Apr 16 12:03 asdasdasd.sql.gz

我希望所有 === 行的长度相同,并且文本始终位于中间,每边各有 1 个 space

在此感谢帮助:)

更新/编辑: 原剧本是这样的:

eecho () { echo ==========================================================================; }

echo_stage () {
  START=1
  END=11
  for (( c=$START; c<=$END; c++ ))
  do
    printf == '-%.0s'
  done
  echo -n " "  " "
  for (( c=$START; c<=$END; c++ ))
  do
    printf == '-%.0s'
  done
  echo
}

stage() {
  eecho
  echo_stage "" ""
  eecho
}

print_date () { echo "======================" $(date) "======================"; }


reload_db() {
  print_date
  rm -rf /var/tmp/db
  mkdir -p /var/tmp/db
  stage "DB - Download from S3"
  aws s3 sync s3://db-backup/latest/ /var/tmp/db --profile=papilon --quiet
  stage "DB - Decompressing"
  pigz -d /var/tmp/db/*
  stage "DB - Restoring Data"
  cd /var/tmp/db
  stage "DB - Restoring Tables"
  for i in `ls -1 *.sql | grep -v "_view.sql"`;do echo $i;mysql db < $i;done
  stage "DB - Restoring Views"
  for i in `ls -1 *.sql | grep  "_view.sql"`;do echo $i;mysql db < $i;done
  stage "DB - Clean up"
  rm -rf /var/tmp/db
  print_date
}


reload_db

此 awk 过滤器将正确调整 === 填充大小,并将标题对齐到中心,如果您通过管道输出命令:

# cmd |

awk '
BEGIN {a[1] = "="}
NF>1 && ~/^=+$/ && $NF~/^=+$/ {
    sub(/^=+/, "")
    sub(/=+$/, "")

    title_len=length([=10=])

    pad = ""
    for (i=1; i<=(74-title_len)/2; ++i) {
            pad=pad"="
    }

    [=10=] = pad [=10=] pad a[title_len%2]
}
1'

这不会包装 ls -l 输出,只有标题。它假定 74 被硬编码为 === 实线的长度(并且不会根据终端大小而改变)。数组a用于在74 - title_len为奇数时多加一个=

示例输出:

====================== Sat Apr 16 12:57:17 EDT 2022 ======================
==========================================================================
======================  Leopard - Download from S3  ======================
==========================================================================
==========================================================================
=======================  Leopard - Decompressing  ========================
==========================================================================
total 1349872
drwxr-xr-x  2 root root     12288 Apr 16 12:57 .
drwxrwxrwt. 4 root root       102 Apr 16 12:57 ..
-rw-r--r--  1 root root 185070885 Apr 16 12:03 asdasdasd.sql.gz
-rw-r--r--  1 root root  40344632 Apr 16 12:03 asdasdas.sql.gz
-rw-r--r--  1 root root     26631 Apr 16 12:03 asdad.sql.gz
-rw-r--r--  1 root root      1679 Apr 16 12:03 asdasd.sql.gz
-rw-r--r--  1 root root      1237 Apr 16 12:03 asd.sql.gz
-rw-r--r--  1 root root   5241900 Apr 16 12:03 asdasd.sql.gz
-rw-r--r--  1 root root      1144 Apr 16 12:03 asdasasd.sql.gz
-rw-r--r--  1 root root    489312 Apr 16 12:03 asdasd.sql.gz
-rw-r--r--  1 root root      1138 Apr 16 12:03 asdasdasd.sql.gz
==========================================================================
====================  NewYorkCity - Download from S3  ====================
==========================================================================
==========================================================================
=================  NewYorkCity - Unloading SSL Example  ==================
==========================================================================
total 1349872
drwxr-xr-x  2 root root     12288 Apr 16 12:57 .
drwxrwxrwt. 4 root root       102 Apr 16 12:57 ..
-rw-r--r--  1 root root 185070885 Apr 16 12:03 asdasdasd.sql.gz
-rw-r--r--  1 root root  40344632 Apr 16 12:03 asdasdas.sql.gz
-rw-r--r--  1 root root     26631 Apr 16 12:03 asdad.sql.gz
-rw-r--r--  1 root root      1679 Apr 16 12:03 asdasd.sql.gz
-rw-r--r--  1 root root      1237 Apr 16 12:03 asd.sql.gz
-rw-r--r--  1 root root   5241900 Apr 16 12:03 asdasd.sql.gz
-rw-r--r--  1 root root      1144 Apr 16 12:03 asdasasd.sql.gz
-rw-r--r--  1 root root    489312 Apr 16 12:03 asdasd.sql.gz
-rw-r--r--  1 root root      1138 Apr 16 12:03 asdasdasd.sql.gz

因为你现在已经发布了你的脚本,我会为纯 bash 添加一个新的答案。

title() {
    local text pad

    (( ${#1} > 70 )) && { echo ""; return; }
    text=${1:+ }${1:+ }

    pad=$( eval "printf %.1s ={1..$(( ( 74 - ${#text} ) / 2 ))}" )

    echo "$pad$text$pad$( (( ${#text} % 2 )) && printf = )"
}

对于 title 'foo bar',此函数打印 foo bar(或最多 70 个字符的任何字符串),两边带有 space,居中并用 [=17= 填充到 74 列].如果字符串超过 70 个字符,则太长而无法填充,因此按原样打印。

================================ foo bar =================================

在没有参数或参数为空的情况下,它打印一条实线 74 =:

==========================================================================
  • 您可以将 = 换成任何单个 ASCII 字符。
  • 您可以将 74 换成任意偶数。同样对于奇数,如果您在最后一行将 && printf 更改为 || printf。 (同时将 70 更改为 N - 4)
  • 您可以为日期调用 title 一次,或者为较大的三行横幅调用三次(请参阅下面的 banner)。

解释:

  • ${#text} 是 bash 表示“$text 的长度”。

  • ${1:+ } 扩展为 space,除非 </code> 为空或未设置。这允许我们将 spaces 添加到字符串的任一端,或者将它们排除在空字符串之外。</p> </li> <li><p><code>={1..10} 扩展为 =1 =2 =3 ... =10printf %.1s 打印每个字符串的第一个字符。结合这些可以让我们重复一个字符串 (=) N 次。

  • 但是我们不能正常使用{1..10}中的变量(或算术)。所以我们需要 eval.

  • 您可能听说过 eval 不好,并且存在安全风险。这通常是正确的,但在这里我们没有将任何未知数据传递给 eval(例如用户输入),并且它不会受到代码注入的影响。 (${#text} 总是扩展为单个数字)

  • 所以我们制作两个长度为 (74 - text-length) / 2 的条,如果文本长度为奇数,则向第二个条添加另一个 =

我还对您的脚本进行了一些更改,您可能会考虑。除了日期和标题,这些与填充无关。标题和横幅功能将适用于您的旧脚本。

title() {
    local text pad

    (( ${#1} > 70 )) && { echo ""; return; }
    text="${1:+ }${1:+ }"

    pad=$( eval "printf %.1s ={1..$(( ( 74 - ${#text} ) / 2 ))}" )

    echo "$pad$text$pad$( (( ${#text} % 2 )) && printf = )"
}

banner() {
    title
    title ""
    title
}

reload_db() {

    local i

    title "$(date)"

    rm -rf /var/tmp/db || exit 1
    mkdir -p /var/tmp/db || exit 1

    banner 'DB - Download from S3'
    aws s3 sync s3://db-backup/latest/ /var/tmp/db --profile=papilon --quiet

    banner 'DB - Decompressing'
    pigz -d /var/tmp/db/*

    banner 'DB - Restoring Data'
    cd /var/tmp/db || exit 1

    banner 'DB - Restoring Tables'
    GLOBIGNORE='*_view.sql'
    for i in *.sql; do
        echo "$i"
        mysql db < "$i"
    done
   GLOBIGNORE=

    banner 'DB - Restoring Views'
    for i in *_view.sql; do
        echo "$i"
        mysql db < "$i"
    done

    banner 'DB - Clean up'
    rm -rf /var/tmp/db

    title "$(date)"
}

至少,如果 cdmkdir 或第一个 rm 失败,您应该提前退出。此外,循环一个未加引号的 ls 命令 sub 是 bad idea。相反,您可以使用 glob 扩展(或 find)。

您也可以连接 SQL 脚本,但这仅在所有命令都以分号结尾时才有效(参见 Run multiple sql files in mysql batch):

    big_title 'DB - Restoring Tables'
    GLOBIGNORE='*_view.sql'
    printf '%s\n' *.sql
    cat *.sql | mysql db
    GLOBIGNORE=

    big_title 'DB - Restoring Views'
    printf '%s\n' *_view.sql
    cat *_view.sql | mysql db