简体   繁体   中英

How to print something to the right-most of the console in Linux shell script

Say I want to search for "ERROR" within a bunch of log files.

I want to print one line for every file that contains "ERROR".

In each line, I want to print the log file path on the left-most edge while the number of "ERROR" on the right-most edge.

I tried using:

printf "%-50s %d" $filePath $errorNumber

...but it's not perfect, since the black console can vary greatly, and the file path sometimes can be quite long.

Just for the pleasure of the eyes, but I am simply incapable of doing so. Can anyone help me to solve this problem?

Using bash and printf :

printf "%-$(( COLUMNS - ${#errorNumber} ))s%s" \
       "$filePath" "$errorNumber"

How it works:

  1. $COLUMNS is the shell's terminal width.

  2. printf does left alignment by putting a - after the % . So printf "%-25s%s\\n" foo bar prints " foo ", then 22 spaces, then " bar ".

  3. bash uses the # as a parameter length variable prefix, so if x=foo , then ${#x} is 3 .


Fancy version, suppose the two variables are longer than will fit in one column; if so print them on as many lines as are needed:

printf "%-$(( COLUMNS * ( 1 + ( ${#filePath} + ${#errorNumber} ) / COLUMNS ) \
          - ${#errorNumber} ))s%s"   "$filePath" "$errorNumber"

Generalized to a function. Syntax is printfLR foo bar , or 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 ;  }

Test with:

# command line args
printfLR foo bar
# stdin
fortune | tr -s ' \t' '\n\n' | paste - - | printfLR

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM