2

文字列の書式設定に問題があります。何をしたいのかはわかっていますが、正確な方法がわかりません。ここのどこかでお役に立てば幸いです。私の問題は次のようになります。

私のスクリプトでは、関数を使用して、標準化されているが可変長のヘッダーとユーザー定義のメッセージ本文を使用するログ出力を書き込みます。メッセージの長さと端末の幅は、メッセージが頻繁にラップアラウンドすることを意味します。私がやりたいことは、メッセージがログでよりフォーマットされて表示されるように、折り返す行に「パディング」を挿入することです。

これは、私の作業コードの一部の適合されたテストされていない抜粋です。それは私がやりたいことを示しています:

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 文字の端末と一致しませんが、例は説明用です。

4

2 に答える 2

1

スクリプト名が is_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...

書式設定に関心がある場合は、ヘッダーを 1 行に配置し、ログ メッセージをその下の行に書式設定してみませんか?

[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
于 2012-12-27T16:25:20.280 に答える
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
}

次に、次のように使用します。

$ # 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.

お役に立てれば!

于 2012-12-27T17:22:06.443 に答える