使用 printf 在 bash 中格式化多行命令输出

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16583320/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 05:26:52  来源:igfitidea点击:

Format multiline command output in bash using printf

linuxbashformattingprintfmultiline

提问by Mike Foxtrot

My Bash script uses printfto print output of some other commands with formatting applied, in the following manner (note the two leading spaces):

我的 Bash 脚本使用printf以下方式打印应用了格式的其他一些命令的输出(注意两个前导空格):

printf "  %-16s %s\n" "foo:" "$(bar)"

The two leading spaces are there, because the first line in the file is a comment, and I like to keep things nicely aligned:

两个前导空格在那里,因为文件中的第一行是注释,我喜欢保持对齐:

# foo
  foo:            bar
  foo:            bar
  ...

This works perfectly fine for commands with one-line output. However, when the output is multiline, the output looses the formatting of the subsequent lines.

这对于具有单行输出的命令非常有效。但是,当输出是多行时,输出会丢失后续行的格式。

For example:

例如:

printf "  %-16s %s\n" "Contents:" "$(ls -a)"

Results in something like this:

结果是这样的:

  Contents:       .
..
foo
bar

Instead, what I am trying to achieve is multiline output, with each line formatted (in columns, if you like), which would look like this (note the lack of "header" in the subsequent lines):

相反,我想要实现的是多行输出,每一行都格式化(如果你愿意,可以在列中),看起来像这样(注意后续行中缺少“标题”):

  Contents:       .
                  ..
                  foo
                  bar

My understanding so far is that printfwith two arguments (the first one being a string, and the other one the result of the given command) treats the second argument as a single string, which can include newline characters within. Therefore, the output is actually correctly formatted, according to what I asked printfto do, but it is not what I am looking for.

到目前为止,我的理解是printf使用两个参数(第一个是字符串,另一个是给定命令的结果)将第二个参数视为单个字符串,其中可以包含换行符。因此,根据我的要求,输出实际上格式正确printf,但这不是我要找的。

I am aware about some of the pitfalls related to parsing the output of commands like ls, which exhausts my current possibilities of solving this problem. Also, it is possible that printfis not the best facility to do this.

我知道与解析诸如 之类的命令的输出相关的一些陷阱ls,这耗尽了我目前解决此问题的可能性。此外,这可能printf不是执行此操作的最佳工具。

I am considering substituting multiline string into comma-separated list, if no solution to this problem is possible, but this would be a last resort.

如果无法解决此问题,我正在考虑将多行字符串替换为逗号分隔的列表,但这将是最后的手段。

What would be the best method to achieve the formatting I need?

实现我需要的格式的最佳方法是什么?

Thanks for your help.

谢谢你的帮助。

采纳答案by clyfish

printf "  %-16s %s\n" "foo:" "$(bar | sed '2,$s/^/                   /g')"

回答by Neville Hillyer

You may find it difficult to apply the same print instructions to a range of commands. Also output from ls can be tedious to examine because it selects an output format depending upon environment variables.

您可能会发现很难将相同的打印指令应用于一系列命令。此外,检查 ls 的输出可能很乏味,因为它根据环境变量选择输出格式。

I found the following worked well for ls on my Mac:

我发现以下内容对我的 Mac 上的 ls 很有效:

x=$(ls -a); 
x=${x//$'\n'/$'\n'                    }; 
printf "   %-16s %s" "Contents:" "$x" $'\n'