我有一个文件,其中包含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
答案 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...
的最后一行开始打印日期。
第一步(将-q
从grep
中删除-您不希望它安静):
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...
的输入,则它们什么也不输出。