我有一个字符串格式化问题,虽然我知道我想做什么,但我不确定如何。我希望这里的某处可以提供帮助。我的问题看起来像这样:
在我的脚本中,我使用函数来编写日志输出,该输出使用标准化但可变长度的标题和用户定义的消息体。消息的长度和终端宽度意味着消息经常环绕。我想要做的是在包装的行中插入“填充”,以便消息在日志中显示更多格式。
这是我工作代码的一部分经过改编和未经测试的摘录。它显示了我想要做的事情:
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
所以,我有一种确定何时填充日志行的方法,我认为sed可以做到这一点。我只是不知道如何。如果有人能指出我正确的方向,我会很感激。
这是使用静态格式生成的示例输出。它显示了我想要达到的目的:
[2012-12-27@15:56:43 test.sh] -> Writing a log file entry that
is wrapped onto the next line
with appropriate formatting...
我希望这能使我想要实现的目标更加清晰。行长度与80字符终端不匹配,但示例是说明性的。
答案 0 :(得分:1)
如果脚本名称为_a_really_long_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
答案 1 :(得分:1)
这是一个可以帮助你(在bash中)的功能:
print_padded() {
local header=$1
local msg=( $2 )
local width=$3
local headerlength=${#header}
local i=0
local spaceleft=$((width-headerlength))
local defaultspace=20
(((spaceleft<0) && (spaceleft=defaultspace)))
local buf=()
local s
printf "%s" "$header"
while ((i<${#msg[@]})); do
if ((${#msg[i]}+1<=spaceleft)); then
printf " %s" "${msg[i]}"
((spaceleft-=${#msg[i++]}+1))
else
echo
(((spaceleft=width-headerlength)<0 && (spaceleft=defaultspace)))
while ((${#msg[i]}>=spaceleft)); do
(((s=width-${#msg[i]})<0 && (s=0)))
printf "%${s}s%s\n" '' "${msg[i++]}"
done
printf "%${headerlength}s" ''
fi
done
echo
}
然后使用as,例如,
$ # 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.
希望这有帮助!