2013-08-28 61 views
0

我在CentOS上有一個很長的,維護得不好的bash腳本,其中有很多使用echo的日誌行,並且其中有三分之一左右是登錄日誌文件。我想修改其餘的回聲線,以便將這些日誌文件發送到此日誌文件中。添加到缺少模式的行的末尾

下面是一個例子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每一行的末尾。

有沒有人有任何好點子?

回答

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 
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 /{ [email protected] \?| \?tee -a [email protected]@; [email protected] @log @; }' file 
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所說,可能會有很多邊界情況會使程序失敗。