Bash printf 列中 arg 中的多行

noo*_*lag 4 bash printf

我已经摆弄这个好几个小时了,但无法让它工作,所以也许我的方法是错误的。

我想漂亮地显示消息的多行,因此“标题”位于左侧,然后消息与列中的消息对齐,例如,如下所示:

WARNING: The quick brown fox jumped over the lazy dog.
         Sphinx of black quartz, judge my vow.
         How quickly daft jumping zebras vex!
Run Code Online (Sandbox Code Playgroud)

或者

NOTE: This happened.
      Foo bar.
Run Code Online (Sandbox Code Playgroud)

等等。

我试图根据我能找到的一些答案来做到这一点printfcolumn但正如我所说,也许这种方法永远行不通?

目前,我有第一个字符串作为printf“标题”,然后其余的参数是与之对齐的消息,如下所示:

#!/bin/bash

warn() {
  printf '%s+%s\n' 'WARNING:' "${@}" | column --table --separator '+'
}

warn "The quick brown fox jumped over the lazy dog." \
     "+Sphinx of black quartz, judge my vow." \
     "+How quickly daft jumping zebras vex!"
Run Code Online (Sandbox Code Playgroud)

这可以类似地完成吗?或者最好的方法/其他方法是什么?

实际输出:

WARNING:  The quick brown fox jumped over the lazy dog.    
          Sphinx of black quartz, judge my vow.            How quickly daft jumping zebras vex!
Run Code Online (Sandbox Code Playgroud)

Léa*_*ris 9

这是一个不需要循环和子 shell 的实现:

#!/usr/bin/env bash

taggedMessage() {
  # Prints first message with prepend tag
  printf '%s %s\n' "${1:?}" "${2:?}"

  [ $# -gt 2 ] || return # Returns if only one message

  # Constructs blank filler of same length as tag
  printf -v filler '%*s' ${#1} ''

  shift 2 # Shifts arguments at 2nd message

  # Prints remaining messages with prepend filler
  printf %s\\n "${@/#/$filler }"
}

warn() { taggedMessage 'WARNING:' "$@";}

warn "The quick brown fox jumped over the lazy dog." \
     "Sphinx of black quartz, judge my vow." \
     "How quickly daft jumping zebras vex!"

taggedMessage 'SINGLE:' 'A single-line message.'

taggedMessage 'RANDOM TAG:' \
    "The quick brown fox jumped over the lazy dog." \
    "Sphinx of black quartz, judge my vow." \
    "How quickly daft jumping zebras vex!"
Run Code Online (Sandbox Code Playgroud)


Gro*_*obu 5

如果去掉column管道,printf '%s+%s\n' 'WARNING:' "${@}"会产生:

WARNING:+The quick brown fox jumped over the lazy dog.
+Sphinx of black quartz, judge my vow.++How quickly daft jumping zebras vex!
Run Code Online (Sandbox Code Playgroud)

printf根据规范,这是处理输入的方式%s+%s\n

  • 第一遍:
    • 第一个标记是“警告:”
    • 第二个标记是“敏捷的棕色狐狸跳过了懒狗”。
    • 产生“警告:+快速...狗\n”并提供给column. 一切都好。
  • 第二遍:
    • 第一个令牌是“+黑石英狮身人面像,审判我的誓言。”
    • 第二个标记是“+愚蠢的斑马跳得多快啊!”
    • 产生“+狮身人面像......誓言++多快......烦恼!”
    • “+Sphinx of ....”部分将正确显示在下一行第二列中
    • “++多快啊……烦人!” 将出现在同一行(如“Sphinx ...”)(而需要将其移动到下面的下一行),在第三列(两个“+”分隔符)

这是对您的功能的建议warn

warn() {
  local Title='WARNING'
  local Separator='+'
  local FirstArg="${1:-(default message)}"

  # if arguments were supplied, zap first one
  # and prepend SEPARATOR to remaining others
  if test "$#" -gt 0
     then shift
     for _ in "$@"
     do  set -- "$@" "${Separator}${1}"
         shift
     done
  fi

  printf '%s\n' "${Title}:${Separator}${FirstArg}" "$@" | column -t -s "${Separator}"
}
Run Code Online (Sandbox Code Playgroud)

通过像这样的调用

warn "The quick brown fox jumped over the lazy dog." \
     "Sphinx of black quartz, judge my vow." \
     "How quickly daft jumping zebras vex!"
Run Code Online (Sandbox Code Playgroud)

...它将提供以下内容column

WARNING:+The quick brown fox jumped over the lazy dog.
+Sphinx of black quartz, judge my vow.
+How quickly daft jumping zebras vex!
Run Code Online (Sandbox Code Playgroud)

...最终将显示如下:

WARNING:  The quick brown fox jumped over the lazy dog.
          Sphinx of black quartz, judge my vow.
          How quickly daft jumping zebras vex!
Run Code Online (Sandbox Code Playgroud)

在 Debian 11 下作为/bin/sh脚本进行测试。

希望有帮助。