我在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
',则后跟 not '{{ 1}}',然后在行的末尾追加'| tee
'。
经过大量的搜索,这是我迄今为止最好的:
| tee -a my.log
但这只会将sed --in-place=_BACKUP '/^.*echo\(?!\| tee$\)*/ s/$/ \| tee -a my.log/' myscript.sh
附加到包含| tee -a my.log
的每一行的末尾。
有没有人有什么好主意?
答案 0 :(得分: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
答案 1 :(得分: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
答案 2 :(得分: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所说,可能有许多边缘情况导致程序失败。