use*_*209 1 linux format shell
假设我想在一堆日志文件中搜索"ERROR".
我想为包含"ERROR"的每个文件打印一行.
在每一行中,我想打印最左边的日志文件路径,而最右边的"ERROR"数.
我试过用:
printf "%-50s %d" $filePath $errorNumber
Run Code Online (Sandbox Code Playgroud)
...但它并不完美,因为黑色控制台可能会有很大差异,文件路径有时可能会很长.
只是为了眼睛的快乐,但我根本无法这样做.任何人都可以帮我解决这个问题吗?
使用bash和printf:
printf "%-$(( COLUMNS - ${#errorNumber} ))s%s" \
"$filePath" "$errorNumber"
Run Code Online (Sandbox Code Playgroud)
这个怎么运作:
$COLUMNS 是shell的终端宽度.
printf通过放置一个-后来做左对齐%.所以printf "%-25s%s\n" foo bar打印" foo ",然后打印22个空格,然后打印" bar ".
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)