0

私は CentOS に長くてよく維持されていない bash スクリプトを持っています。多くのログ行がエコーを使用しており、そのうちの約 3 分の 1 がログ ファイルに記録されています。残りのエコー行を変更して、このログ ファイルにもティーを追加したいと考えています。

myscript.sh の例を次に示します。

command1
echo "hi1"
echo "hi2" | tee -a my.log
echo "hi3 tee"
command2

このファイルで何かを実行した後、内容を次のように変更したいと思います。

command1
echo "hi1" | tee -a my.log
echo "hi2" | tee -a my.log
echo "hi3 tee" | tee -a my.log
command2

sed または awk を正規表現で使用する必要があると考えています。ロジックは、「行に ' ' が含まれecho、その後に ' 'が含まれていない場合、行末に' '| teeを追加| tee -a my.logする」です。

いろいろ検索した結果、これが今までで一番いいです。

sed --in-place=_BACKUP '/^.*echo\(?!\| tee$\)*/ s/$/ \| tee -a my.log/' myscript.sh

しかし、これは.| tee -a my.logを含む各行の末尾に追加されるだけechoです。

誰か良いアイデアはありますか?

4

3 に答える 3

3

これでうまくいくはずです(ただし、コーナーケースがたくさん来ると思います)

$ awk '/^echo/&&!/tee -a my.log$/{$0=$0"| tee -a my.log"}1' file
command1
echo "hi1"| tee -a my.log
echo "hi2" | tee -a my.log
echo "hi3 tee"| tee -a my.log
command2

説明:

/^echo/                  # If the line start echo
&&                       # Logical AND
!/tee -a my.log$/        # Doesn't end with tee -a my.log
{$0=$0"| tee -a my.log"} # Append the tee command to the end of the line
1                        # Awk idiom to print all the lines in the file
于 2013-08-28T20:36:35.410 に答える
2

実際には、ファイルの fd を開き、関数を使用してメッセージをログに記録することをお勧めします。

exec 40>>my.log

function log {
    echo "$1"
    echo "$1" >&40
}

command1
log "hi1"
log "hi2"
log "hi3"
command2

exec 40>&-

あなたのスクリプトは実際にその方法でより速く実行され、tee を呼び出し続ける必要がなくなります。

このようなコマンドは、ファイルをそれに変換するための開始になる可能性があります。

sed '/echo /{ s@ \?| \?tee -a my.log@@; s@echo @log @; }' file
于 2013-08-28T20:37:20.337 に答える
0

少し学んだだけでawk、気分は最高です!これを書き、サンプル入力でテストしました:

awk '{if ($0 ~ "^echo" && $0 !~ "tee -a") \
        print $0" | tee -a my.log"; \
      else \
        print $0}' myscript.sh

Where
$0    #means the current line of input
~     #match the following regex
!~    #not match the following regex

sudo_O が言ったように、プログラムが失敗する多くのエッジ ケースが存在する可能性があります。

于 2013-08-30T13:58:04.980 に答える