将文件中的行从正则表达式合并到“lineify”多行日志日志文件

将文件中的行从正则表达式合并到“lineify”多行日志日志文件

标准 unix 命令行工具(grep、cut、sed 等)都一次运行一行。几乎总是这样,这很棒。

不过我正在尝试解析一些 postgresql 慢查询日志。每个条目在开始处都有一些内容(日期时间、持续时间),然后是 SQL 查询。 SQL 查询可能有换行符,因此日志文件中的每个“条目”可能会多于 1 行(因为查询中的换行符会直接放入日志文件中,而不是转义)。我想以某种方式将这些行“合并”在一起,以便 1 行 = 1 个日志文件条目。现在,有时一个条目完全在一行上,有时一个条目分布在多达 10 行中。

有没有一个unix工具可以以某种方式“lineify”这个文件?我想给它一个(PCRE)正则表达式,它会根据它分割行/标准输入。此正则表达式出现之间的所有实际换行符应替换为"\n"或 我可以指定的内容。

可能有一个衬垫可以用 perl 来做到这一点,但我想在我自己制作之前看看是否有人已经制作了这个程序。

更新:我可以提供示例数据,但我想知道一般问题。 SQL Server 可能会生成多行日志文件。我想要一个通用的解决方案将任何文件转换为换行符分隔的 unix-y 样式文件。

答案1

使用 gawk,您可以使用 PCRE 表达式(的子集)作为寄存器分隔符 ( RS),定义不同的输出寄存器分隔符 ( ORS) 并替换\n

例子:

gawk 'BEGIN {RS="[ ]*;\n"; ORS="\n===\n"}
            {gsub("\n","\\n");   print} '

在这个例子中:

  • [ ]*;\n 寄存器在输入中用分隔
  • 寄存器在输出中用“\n===\n”分隔

答案2

逐行解析日志文件行并抑制所有 \n。当你看到一个新条目时,除了第一次之外,首先写\n。
你说了Each entry has some stuff at the start (datetime, duration),但你没有举例。好吧,我就叫它NEW_ENTRY,你可以修改。

inStatement=0
cat logfile | while read -r line; do
   if [[ ${inStatement} = 0 ]]; then
      inStatement=1
   else
      [[ ${line} = NEW_ENTRY* ]] && echo
   fi
   echo -n "${line} "
done
echo

相关内容