Unix 命令列出日志文件末尾的部分,从仅包含连字符的行到文件末尾

Unix 命令列出日志文件末尾的部分,从仅包含连字符的行到文件末尾

我有一个很长的日志文件,其中每个条目都以仅包含连字符的行开头。

答案1

你可以使用 shell 脚本来做这件事:

#!/bin/bash
if [[ -z "$1" ]] ; then
    echo Usage: $0 '<inputFile>'
    exit 1
fi
line=$(grep -n '^--*$' "$1" | tail -1 | sed 's/:.*//')
if [[ -z "${line}" ]] ; then
    cat "$1"
else
    sed "1,${line}d" "$1"
fi

给定输入文件:

this is line 1
-------
this is line 3
-------
this is line 5
this is line 6

它产生:

this is line 5
this is line 6

为了解释,grep -n产生了一系列类似这样的行:

2:-------
4:-------

其中24是行号。thentail -1会过滤掉除最后一个之外的所有内容,而sed会删除从冒号到行尾的所有内容,只留下行号

然后,如果没有符合所需模式的行,它只会输出整个文件。否则它会删除 1 和最后一个连字符行之间的所有行。


顺便说一句,我最初的答案包括这个awk代码片段,它只会处理该文件一次:

awk '/^--*$/{s=""}{s=s$0"\n";}END{print s}'

但是,请记住,它的工作原理是将行累积成一个字符串,并在找到连字符时清除该字符串。然后,最后,它只是输出字符串(最后一个连字符行之后的所有行)。

虽然乍一看,这似乎更有效率,但实际上并非如此。在我的系统上进行的(诚然不是详尽的)测试中,它实际上运行得相当慢,我认为这与正在进行的许多字符串附加有关。事实上,尽管脚本解决方案对数据进行了多次传递(可能是因为每次传递的功能非常有限),但它似乎更快。

答案2

awk -vRS="-+" 'END{print}' ORS="" file

答案3

你也可以用 sed 来做:

% cat t.txt
this is line 1
this is line 2
-------
this is line 3
----
this is line 4
-------
this is line 5
this is line 6
% sed -n -e '/^---*/{h;d;}' -e H -e '${g;p;}' t.txt
-------
this is line 5
this is line 6
% 

(对于某些 sed,这些分号必须是换行符)。

答案4

tac file | grep -B 10000 -m 1 -- '------' | tac

相关内容