多个 Grep 搜索

多个 Grep 搜索

我希望获取与测试字符串匹配的日志文件的最后一行并将其输出到另一个日志文件。

我需要测试许多不同的文本字符串,并根据输出发送到不同的日志文件。

我正在使用这个:

tail -f -n 1 input.log | grep string1 >>output1.log

然后我想像这样重复测试:

tail -f -n 1 input.log | grep string2 >>output2.log
tail -f -n 1 input.log | grep string3 >>output3.log

如何在单个高效的 bash 脚本中实现这一目标?

答案1

使用 awk 而不是 grep:

awk '/string1/ { print >> "output1.log" ; fflush() }
     /string2/ { print >> "output2.log" ; fflush() }
     /string3/ { print >> "output3.log" ; fflush() }' input.log

这输出全部匹配行到各自的output.log 文件。那是因为我无法理解你的矛盾tail -ftail -n 1要求。如果您确实希望它input.log从当前最后一行开始,请通过管道tail -f -n 1输入awk脚本并删除input.log该行末尾的 。例如

tail -f -n 1 input.log | awk '...same awk script as above...'

tee你也可以用andgrep来完成流程替代 (但会明显慢一些):

tee >(grep --line-buffered string1 >> output1.log) \
    >(grep --line-buffered string2 >> output2.log) \
    >(grep --line-buffered string3 >> output3.log) < input.log

或者

tail -f -n 1 input.log | tee .....

笔记:仅当您将(或其他一些永无止境的过程)的输出通过管道传输到或 时,才需要解决fflush()方案中的awk和解决--line-buffered方案中的选项。teetail -fawktee

如果没有它们,只有当输出缓冲区(awk 或 grep)已满时才会写入输出文件 - 如果作业在缓冲区中有未写入的输出(例如按 Ctrl-C)时中止,则任何输出仍在缓冲区将会丢失。

使用它们,两种解决方案的运行速度都会慢得多(因为它们在每次写入时都会刷新输出) - 但这不太可能很重要,除非输入文件非常大。

顺便说一句,当输入结束时这不是问题 - 在这种情况下,awk 和 grep 都会在退出之前自动刷新其输出缓冲区。

另一种替代方法是在子 shell 中运行管道awk(或),捕获并忽略来自 Ctrl-C 的中断信号。tee例如

tail -f input.log | ( 
  trap '' INT
  awk '/string1/ { print >> "output1.log" }
       /string2/ { print >> "output2.log" }
       /string3/ { print >> "output3.log" }'
  )

tail -f按 Ctrl-C 会影响(杀死),但运行的子 shell会awk忽略它。 awk刷新其输出缓冲区并在tail由于其输入已完成而被终止时退出。

在 awk 脚本中捕获 Ctrl-C另一个例子/解释。


如果您不希望它遵循日志文件,则不要使用tail's-f选项。

只需使用tail -n 1 | .....或查看盖伊的答案,它将所有三个字符串的最后一个匹配项打印到各自的输出文件中。

答案2

编辑来自 cas 的解决方案,以专注于您的生产线。

我希望获取与测试字符串匹配的日志文件的最后一行并将其输出到另一个日志文件。

awk '
    # every time theres a match, save that line into a variable
    /string1/ { str1 = $0 }
    /string2/ { str2 = $0 }
    /string3/ { str3 = $0 }
    END {
      # and only print to file after reading the whole log.
      print str1 >> "output1.log"
      print str2 >> "output2.log"
      print str3 >> "output3.log" 
}' input.log

答案3

输入文件

praveen
ajay
abhi
praveen
ajay
abhi
kiran
tomato

我们的要求是搜索不同的文本字符串并将输出写入不同的文本文件

我已经使用 for 循环和 sed 命令来实现相同的目的

我尝试搜索内容 praveen、ajay、abhi 并将输出保存在 contentsearch.txt 中

脚本

for i in praveen ajay abhi; do sed -n "/$i/p" input.txt > $i.txt; done

下面将是输出

praveen.txt  will contains line where praveen is present
ajay.txt will contains line where ajay is present
abhi.txt will contains where abhi is present

=================================================== ===========================

如果您想搜索与测试字符串匹配的日志文件的最后一行并将其输出到其他文件,请使用以下命令

sed -n '/Contentsearch/p' input.txt | tail -1 > output.txt

相关内容