0

我在 CentOS 上有一个很长的、维护得不好的 bash 脚本,其中有许多使用 echo 的日志行,其中大约三分之一的 tee-ing 到一个日志文件中。我想修改其余的回显行,以便也进入此日志文件。

这是一个示例 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 回答