如何使用 echo 或 print 对齐多行

Kam*_*deo 7 text-processing

我有一个脚本可以根据 fstab 下列出的条目检查已安装的文件系统,我在这里面临的问题是保持输出对齐。

下面是脚本输出:

/  is mounted OK
/boot  is mounted OK
/was8  is mounted OK
/was8/slogs  is mounted OK
/was8/cluster  is mounted OK
/was8/working  is mounted OK
/was8/app  is mounted OK
/was8/tools  is mounted OK
/was8/plugin  is mounted OK
/was8/coreproduct  is mounted OK
...
Run Code Online (Sandbox Code Playgroud)

我想保持这些线对齐,所以它应该是这样的:

/  is mounted                       OK
/boot  is mounted                   OK
/was8  is mounted                   OK
/was8/slogs  is mounted             OK
/was8/cluster  is mounted           OK
/was8/working  is mounted           OK
/was8/app  is mounted               OK
/was8/tools  is mounted             OK
/was8/plugin  is mounted            OK
/was8/coreproduct  is mounted       OK
...
Run Code Online (Sandbox Code Playgroud)

我试过 column 和 xargs 无法得到想要的结果。有人可以帮我弄这个吗。

ilk*_*chu 12

一般情况下,在进行打印时,可以将格式字符串中的宽度设置为printf. %-20s将在 20 个字符(*)宽的字段上打印字符串,除非它溢出。%-20.20s将使它成为 20 个字符并丢弃任何溢出的部分。

(* 虽然例如 Bashprintf实际上计算字节数。可以通过äUTF-8 中的字符看出差异。)

所以,例如

printf "%-40s %s\n" "$mountpoint  is mounted" "$status"
Run Code Online (Sandbox Code Playgroud)

将使第一部分(至少)40 个字符宽:

/was8/coreproduct  is mounted            OK
...
Run Code Online (Sandbox Code Playgroud)

或者,如果您需要对这样的输入进行后处理,您可以使用 Perl 或 awk:

perl -pe 's/(.*) +(\S+)$/ sprintf "%-40s %s", $1, $2 /e'  < file

awk '{s=$NF; sub(/ *[^ ]+ *$/, "", $0); printf "%-40s %s\n", $0, s}'  < file
Run Code Online (Sandbox Code Playgroud)

两者基本上都将最后一个非空白字符串分开,然后将两个部分与第一个一起打印在一个固定宽度的字段上。


或者,如果您不关心完全按照原样保持字段之间的分隔,@ JJoao评论的更简单的解决方案是:

awk '{s=$NF; NF-- ; printf "%-40s %s\n", $0, s}' < file
Run Code Online (Sandbox Code Playgroud)

这会产生以下输出。请注意,之前的两个空格空白is mounted被折叠为一个。发生这种情况是因为在修改或任何字段时awk重建整个字段。$0NF

/was8/coreproduct is mounted             OK
Run Code Online (Sandbox Code Playgroud)

  • 请注意,`printf "%.20s"` 仅使用 `zsh` 或 `fish` `printf` 打印 20 _character_ 宽的字符串。对于其他实现,它是 20 _byte_ 宽,因为 POSIX(不合理)需要。使用 ksh93 的 `printf` 内置,另见 `printf "%20Ls"` 将宽度作为显示宽度(考虑零宽度或双宽度字符)。对于 awk,YMMV 取决于实现,使用 `perl`,使用 `-Mopen=locale` 来处理语言环境字符集中的字符。 (3认同)

JJo*_*oao 6

只是有点混淆 Perl:

perl -ne 'printf "%-40s %s", /(.*) (.*)/s'
Run Code Online (Sandbox Code Playgroud)


Tho*_*hor 4

一种方法是在状态代码之前引入一个选项卡,例如:

<input rev | sed 's/ /\t/' | rev | column -s $'\t' -t
Run Code Online (Sandbox Code Playgroud)

输出:

/  is mounted                        OK
/boot  is mounted                    OK
/was8  is mounted                    OK
/was8/slogs  is mounted              OK
/was8/cluster  is mounted            OK
/was8/working  is mounted            OK
/was8/app  is mounted                OK
/was8/tools  is mounted              OK
/was8/plugin  is mounted             OK
/was8/coreproduct  is mounted        OK
/was8/ihs  is mounted                OK
/was8/backup  is mounted             OK
/was8/ihs/logs  is mounted           OK
/was8/wsdm  is mounted               OK
/was8/ws  is mounted                 OK
/was8/ihs/logs/analysis  is mounted  OK
Run Code Online (Sandbox Code Playgroud)