如何在Linux shell脚本中将内容打印到最右边的控制台

use*_*209 1 linux format shell

假设我想在一堆日志文件中搜索"ERROR".

我想为包含"ERROR"的每个文件打印一行.

在每一行中,我想打印最左边的日志文件路径,而最右边的"ERROR"数.

我试过用:

printf "%-50s %d" $filePath $errorNumber
Run Code Online (Sandbox Code Playgroud)

...但它并不完美,因为黑色控制台可能会有很大差异,文件路径有时可能会很长.

只是为了眼睛的快乐,但我根本无法这样做.任何人都可以帮我解决这个问题吗?

agc*_*agc 5

使用bashprintf:

printf "%-$(( COLUMNS - ${#errorNumber} ))s%s" \
       "$filePath" "$errorNumber"
Run Code Online (Sandbox Code Playgroud)

这个怎么运作:

  1. $COLUMNS 是shell的终端宽度.

  2. printf通过放置一个-后来做左对齐%.所以printf "%-25s%s\n" foo bar打印" foo ",然后打印22个空格,然后打印" bar ".

  3. bash使用#作为参数长度的变量前缀,所以if x=foo,${#x}则为3.


花哨的版本,假设两个变量长于一列中的变量; 如果是这样的话,可以根据需要将它们打印出来:

printf "%-$(( COLUMNS * ( 1 + ( ${#filePath} + ${#errorNumber} ) / COLUMNS ) \
          - ${#errorNumber} ))s%s"   "$filePath" "$errorNumber"
Run Code Online (Sandbox Code Playgroud)

推广到一个函数.语法是printfLR foo bar,或printfLR < file:

printfLR() { if [ "$1" ] ; then echo "$@" ; else cat ; fi |
             while read l r ; do
                 printf "%-$(( ( 1 + ( ${#l} + ${#r} ) / COLUMNS ) \
                              * COLUMNS - ${#r} ))s%s"   "$l" "$r"
             done ;  }
Run Code Online (Sandbox Code Playgroud)

测试:

# command line args
printfLR foo bar
# stdin
fortune | tr -s ' \t' '\n\n' | paste - - | printfLR
Run Code Online (Sandbox Code Playgroud)