Bash:处理日志文件输出的格式
我有一个字符串格式的问题,虽然我知道我想做什么,但我不知道到底怎么做。我希望这里的某个地方能帮上忙。我的问题是这样的: 在我的脚本中,我使用函数编写日志输出,日志输出使用标准化但长度可变的头和用户定义的消息体。消息的长度和终端宽度意味着消息通常会环绕。我想做的是在换行符中插入“padding”,以便消息在日志中显示的格式更高 这里是我工作代码的一部分经过改编的未经测试的摘录。它显示了我想做什么:Bash:处理日志文件输出的格式,bash,sed,string-formatting,Bash,Sed,String Formatting,我有一个字符串格式的问题,虽然我知道我想做什么,但我不知道到底怎么做。我希望这里的某个地方能帮上忙。我的问题是这样的: 在我的脚本中,我使用函数编写日志输出,日志输出使用标准化但长度可变的头和用户定义的消息体。消息的长度和终端宽度意味着消息通常会环绕。我想做的是在换行符中插入“padding”,以便消息在日志中显示的格式更高 这里是我工作代码的一部分经过改编的未经测试的摘录。它显示了我想做什么: local __mgs_hdr="[${__DATE}@${__TIME} ${__script}]
local __mgs_hdr="[${__DATE}@${__TIME} ${__script}] -> "
local __msg_body="${1}"
local __hdrlen=$(expr length $__msg_hdr)
local __msglen=$(expr length $__msg_body)
local __max_msglen=$(expr 80 - $__hdrlen)
local __line=""
if [ $__msglen -gt $__max_mslen ]; then # we need to format the message
# Insert newline followed by "$__hdrlen" whitespaces into $__msq_body at $_hdrlen intervals
# to align/justify log lines as blocks of text for each log header entry
# Replace the : with a command to format $__line
:
else
__line="${__msg_hdr}${__msg_body}"
fi
所以,我有一种方法来确定何时填充一条记录线,我想我可以做到这一点。我只是不知道怎么做。如果有人能给我指出正确的方向,我将不胜感激
下面是一个使用静态格式生成的示例输出。它显示了我想要达到的目标:
[2012-12-27@15:56:43 test.sh] -> Writing a log file entry that
is wrapped onto the next line
with appropriate formatting...
我希望这能让我努力实现的目标更加清晰。行长与80个字符的终端不匹配,但示例是说明性的。如果脚本名为“a\u really\u long\u name.sh会发生什么
[2012-12-27@15:56:43 is_a_really_long_name.sh] -> Writing a lo
g file entry
that is wrapp
ed onto the n
ext line with
appropriate f
ormatting...
如果您关心格式化,那么为什么不将头放在一行上,将日志消息格式化在下面的行上呢
[2012-12-27@15:56:43 is_a_really_long_name.sh] ->
Writing a log file entry that is wrapped onto the next line with appropriate
formatting...
一些代码-前者
#!/bin/bash
headerlen=40
maxlinelen=79
linelen=$maxlinelen-headerlen
spaces=" "
msg="This is a message that needs to be split into chunks that are the same width. For illustrative purpose only. Your milage mag vary."
msglen=${#msg}
start=0
while [ $start -lt $msglen ]
do
echo -n "${spaces:1:$headerlen}"
echo "${msg:$start:$linelen}"
let start=$start+$linelen
done
如果你想做后一件事,那么你可以使用类似这样的方法来分割你的消息
#!/bin/bash
linelen=10
msg="This is a message that needs to be split into chunks that are the same width. For illustrative purpose only. Your milage mag vary."
msglen=${#msg}
start=0
while [ $start -lt $msglen ]
do
echo "${msg:$start:$linelen}"
let start=$start+$linelen
done
这里有一个函数可以帮助您(在bash中): 现在,我希望您的消息中不会有任何格式垃圾(例如,颜色代码等),否则此脚本将失败得很惨 它将换行符(在空格处)拆分为单词。正如您将在第一个输出中看到的,如果一行太长而无法容纳,那么它将被放置在自己的一行上(如果可能的话) <>如果你不在意中间的话,那就容易多了:
print_padded() {
local header=$1
local msg=$2
local width=$3
local headerlength=${#header}
local i
local msgspace=$((width-headerlength))
(((msgspace<0) && (msgspace=20)))
printf "%s %s\n" "$header" "${msg:$i:$msgspace}"
for ((i=msgspace;i<${#msg};i+=msgspace)); do
printf "%${headerlength}s %s\n" '' "${msg:$i:$msgspace}"
done
}
希望这有帮助 你最好举一个输入和预期输出的例子,而不是只说你做了什么更新问题…
man printf
。祝你好运。我喜欢你的空格
变量,但与其说它是一个严肃的解决方案,不如说它是一个肮脏的(容易破坏的)黑客printf
更合适。另外,let
已被弃用,请改用shell算法。顺便说一句,shell算法将使您能够以更好的方式在while
循环中编写测试:-/
是的,我昨晚考虑了标题长度大于术语宽度的场景。我需要处理这个问题——可能是从加长的标题长度中减去术语宽度。@d_w_r:我花了很多年的时间处理日志文件,老实说,我从来并没有在一行格式上遇到过任何问题。不过,你的“漂亮”日志文件很快就会变得令人恼火,例如,我无法对某个特定术语进行grep,并期望获得与之相关的整个日志条目。这非常有趣,并且会很好地映射到我所做的事情,只需几个mod。谢谢:)
$ # Demo with 40 columns...
$ msg="Writing a log file entry that is wrapped onto the next line with appropriate formatting..."
$ print_padded "[2012-12-27@15:56:43 test.sh] ->" "$msg" 40
[2012-12-27@15:56:43 test.sh] -> Writing
a log
file
entry
that is
wrapped
onto
the
next
line
with
appropriate
formatting...
$ # Demo with 60 columns:
$ loremipsum="Lorem ipsum dolor sit amet, consectetur adipiscing \
elit. Duis erat purus, vestibulum non sollicitudin ornare, aliquam \
nec mi. In vulputate velit ut felis porta tincidunt. Integer odio \
odio, ullamcorper id ultricies a, fermentum vitae augue. \
Nunc sapien ipsum, dignissim sit amet eleifend eu, suscipit sed eros. \
In hac habitasse platea dictumst. Morbi feugiat interdum ligula \
eu consectetur. Sed congue lacinia felis, a adipiscing nibh \
aliquam in. Vestibulum ante ipsum primis in faucibus orci luctus \
et ultrices posuere cubilia Curae; Proin faucibus ultrices tincidunt."
$ print_padded "loremipsum ->" "$loremipsum" 60
loremipsum -> Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Duis erat purus, vestibulum
non sollicitudin ornare, aliquam nec mi. In
vulputate velit ut felis porta tincidunt.
Integer odio odio, ullamcorper id ultricies a,
fermentum vitae augue. Nunc sapien ipsum,
dignissim sit amet eleifend eu, suscipit sed
eros. In hac habitasse platea dictumst. Morbi
feugiat interdum ligula eu consectetur. Sed
congue lacinia felis, a adipiscing nibh
aliquam in. Vestibulum ante ipsum primis in
faucibus orci luctus et ultrices posuere
cubilia Curae; Proin faucibus ultrices
tincidunt.
print_padded() {
local header=$1
local msg=$2
local width=$3
local headerlength=${#header}
local i
local msgspace=$((width-headerlength))
(((msgspace<0) && (msgspace=20)))
printf "%s %s\n" "$header" "${msg:$i:$msgspace}"
for ((i=msgspace;i<${#msg};i+=msgspace)); do
printf "%${headerlength}s %s\n" '' "${msg:$i:$msgspace}"
done
}
$ # Demo with 40 columns...
$ msg="Writing a log file entry that is wrapped onto the next line with appropriate formatting..."
$ print_padded "[2012-12-27@15:56:43 test.sh] ->" "$msg" 40
[2012-12-27@15:56:43 test.sh] -> Writing
a log fi
le entry
that is
wrapped
onto th
e next l
ine with
appropr
iate for
matting.
$ # Demo with 60 columns:
$ loremipsum="Lorem ipsum dolor sit amet, consectetur adipiscing \
elit. Duis erat purus, vestibulum non sollicitudin ornare, aliquam \
nec mi. In vulputate velit ut felis porta tincidunt. Integer odio \
odio, ullamcorper id ultricies a, fermentum vitae augue. \
Nunc sapien ipsum, dignissim sit amet eleifend eu, suscipit sed eros. \
In hac habitasse platea dictumst. Morbi feugiat interdum ligula \
eu consectetur. Sed congue lacinia felis, a adipiscing nibh \
aliquam in. Vestibulum ante ipsum primis in faucibus orci luctus \
et ultrices posuere cubilia Curae; Proin faucibus ultrices tincidunt."
$ print_padded "loremipsum ->" "$loremipsum" 60
loremipsum -> Lorem ipsum dolor sit amet, consectetur adipisc
ing elit. Duis erat purus, vestibulum non solli
citudin ornare, aliquam nec mi. In vulputate ve
lit ut felis porta tincidunt. Integer odio odio
, ullamcorper id ultricies a, fermentum vitae a
ugue. Nunc sapien ipsum, dignissim sit amet ele
ifend eu, suscipit sed eros. In hac habitasse p
latea dictumst. Morbi feugiat interdum ligula e
u consectetur. Sed congue lacinia felis, a adip
iscing nibh aliquam in. Vestibulum ante ipsum p
rimis in faucibus orci luctus et ultrices posue
re cubilia Curae; Proin faucibus ultrices tinci
dunt.