2

我有一个写入多行事件的日志文件。一个事件开始于________________并包含 n 行详细说明该事件,并在两个换行符之后结束。每次将事件写入日志文件时,我都想将此多行事件合并为一行并将其输出到另一个文件,该文件将这些事件包含为单行。

我怎样才能在 Linux 中做到这一点?

根据给定的建议,我想出了下面的代码。

tail -f audit.log | perl -pe 'chomp; s/^(_____)/\n$1/' | tr '\r' '\t' |
tr -d '________________________________________________________________________________' > audit_test1.log &    

audit.log但是,在我终止后台作业之前,该文件不会写入任何生成的内容。当我终止工作时,输出将写入audit_test1.log.

我怎样才能解决这个问题?

4

2 回答 2

2

这个 Perl 单线应该或多或少地完成这项工作。这些-pe选项意味着用一个while (<>) { YOUR_SCRIPT; print }循环包围在命令行上指定的脚本,该循环逐行读取输入文件(或标准输入),删除(chomps)换行符,并在任何以_____.

修复一些小问题,例如删除第一个额外的空白行,并在行连接处添加空格,留给 OP 作为练习。:-)

perl -pe 'chomp; s/^(_____)/\n$1/' file > another_file

在后台实时转换日志文件 (&) (tail -f):

tail -f file | perl -pe 'chomp; s/^(_____)/\n$1/' > another_file &
于 2013-09-17T18:41:23.313 回答
0

问题是输出缓冲。你必须让 Perl 无缓冲地运行。

http://mywiki.wooledge.org/BashFAQ/009是有关该主题的众多常见问题解答之一。

您需要在 Perl中设置$| = 1STDOUT无缓冲。tr但是,如果要运行两个实例,还必须设置无缓冲。由于 Perl 可以做所有tr可以做的事情,所以无论如何都可以用 Perl 来做所有的处理。

tail -f audit.log | perl -pe 'BEGIN { $| = 1 } chomp; s/^(_____)/\n$1/;
    tr/\r/\t/; tr/_//d' > audit_test1.log &

如果 Perl 是管道中的最后一个,那么缓冲问题应该会消失,但我将其保留以防万一。

顺便说一句,tr只能替换您给它的每个字符的所有出现,因此重复______80 个字符可能不会达到您的预期。如果您的意图是删除恰好有那么多字符的运行但保留其他字符,那么您最好s/_{80}//在 Perl 中进行。

于 2013-09-19T21:37:31.733 回答