获取最新的匹配字符串值

时间:2018-10-30 01:14:12

标签: linux bash awk sed grep

我有一个文件,其中包含initial...关键字的两个值。我想获取匹配initial...字符串的最新日期。获取日期后,我还需要通过将/替换为-

来格式化日期
---other data
    INFO   | abc 1    | 2018/01/04 20:04:35 | initial...

    INFO   | abc 1    | 2018/02/05 17:01:42 | INFO | new| InitialLauncher | c.t.s.s.setup.launch | initial...

---other data

在上面的示例中,我的输出应为2018-02-05。在这里,我正在获取包含initial...值的行,并且仅获取具有最新日期值的行。然后,我需要去除其余的字符串,仅获取日期值。

我正在使用以下grep,但尚未达到要求。

grep -q -iF "initial..." /tmp/file.log

3 个答案:

答案 0 :(得分:1)

类似这样的东西...

$ awk -F'|' '$NF~/initial\.\.\./ {if(max<$3) max=$3} 
             END  {gsub("/","-",max); 
                   split(max,dt," "); print dt[1]}' file

答案 1 :(得分:1)

Grep仅用于(-o)所需的字符串,将其排序并切成第一个单词:

grep -o '2[0-9]\{3\}/[0-9][0-9]/[0-9][0-9] [0-2][0-9]:[0-5][0-9]:[0-9][0-9] .* | initial' file.txt | sort | cut -d' ' -f1 | tai -1

答案 2 :(得分:1)

使用以后的日期会在文件中稍后显示的知识,仅需要从包含initial...的最后一行开始打印日期。

第一步(将-qgrep中删除-您不希望它安静):

grep -iF 'initial...' /tmp/file.log |
tail -n 1 |
sed -e 's/^[^|]*|[^|]*| *\([^ ]*\) .*/\1/' -e 's%/%-%g'

(第一个)s///命令匹配一系列非管道,然后是管道,再匹配一系列非管道,然后是管道,一个空白,然后捕获一系列非空白,最后匹配一个空格和任何东西;它仅用捕获的字符串替换所有字符串,该字符串是输入行上第二个管道之后的日期字段。 s%%%命令(第二个命令)使用%来代替斜杠,从而避免了s/\//-/g可能引起的混淆,从而将日期重新格式化为ISO 8601格式。

但是我们可能会失去tail

grep -iF 'initial...' /tmp/file.log |
sed -n -e '$ { s/^[^|]*|[^|]*| *\([^ ]*\) .*/\1/; s%/%-%gp; }'

-n禁止正常输出; $仅匹配最后一行;在第二个p操作之后的s///打印结果。

grep相比,用sed编写不区分大小写的固定模式搜索更为方便。尽管可以通过单个sed命令来完成,但是您必须相当努力,将匹配的行保存在保持空间中,然后在最后交换保持和模式空间,并进行替换和打印:

sed -n \
    -e '/[Ii][Nn][Ii][Tt][Ii][Aa][Ll]\.\.\./h' \
    -e '$ { x; s/^[^|]*|[^|]*| *\([^ ]*\) .*/\1/; s%/%-%gp; }' /tmp/file.log

每个都在样本数据上产生输出2018-02-05。如果输入没有initial...的输入,则它们什么也不输出。