Linux awk+;筛选日志文件
为了过滤重复的行,我使用了下面的niceawk命令 示例:Linux awk+;筛选日志文件,linux,perl,bash,awk,sed,Linux,Perl,Bash,Awk,Sed,为了过滤重复的行,我使用了下面的niceawk命令 示例: cat LogFile | awk '!seen[$0]++' [INFO],[02/Jun/2014-19:30:45],EXE,ds1a,INHT VERION , 1.4.4.3-08 [INFO],[02/Jun/2014-19:31:25],EXE,ds1a,INHT VERION , 1.4.4.3-08 [INFO],[02/Jun/2014-19:32:40],EXE,ds1a,INHT VERION , 1.4
cat LogFile | awk '!seen[$0]++'
[INFO],[02/Jun/2014-19:30:45],EXE,ds1a,INHT VERION , 1.4.4.3-08
[INFO],[02/Jun/2014-19:31:25],EXE,ds1a,INHT VERION , 1.4.4.3-08
[INFO],[02/Jun/2014-19:32:40],EXE,ds1a,INHT VERION , 1.4.4.3-08
问题是,在某些情况下,我们需要过滤重复的行,尽管某些字段不同,它们并不重要
比如说
日志文件:
cat LogFile | awk '!seen[$0]++'
[INFO],[02/Jun/2014-19:30:45],EXE,ds1a,INHT VERION , 1.4.4.3-08
[INFO],[02/Jun/2014-19:31:25],EXE,ds1a,INHT VERION , 1.4.4.3-08
[INFO],[02/Jun/2014-19:32:40],EXE,ds1a,INHT VERION , 1.4.4.3-08
请查看此文件-日志文件
我需要删除第三个分隔符“,”中的重复行,直到行尾
无论第三个分隔符前面是什么
所以最后我应该得到这个过滤文件:(应该总是得到列表中的第一个)
所以请帮我完成我的任务
如何从第三个分隔符“,”中筛选LofFile,并忽略以下字段:[INFO]、…..、EXE、
备注–植入也可以使用perl一行代码和GNU awk for gensub():
对于任何支持重新间隔的awk(大多数现代awk):
你可以有:
awk 'BEGIN{FS=OFS=","}{o=$0;$1=$2=$3=""}!seen[$0]++{print o;}' ...
使用perl一行程序:
perl -lne '$k = s/(.*?,){3}//r; print if !$seen{$k}++' file.log
产出:
[INFO],[02/Jun/2014-19:30:45],EXE,ds1a,INHT VERION , 1.4.4.3-08
说明:
开关:
:启用行结束处理。(仅当日志文件的最后一行缺少新行时才需要)-l
:为输入文件中的每一行创建-n
循环李>while(){..}
:告诉-e
在命令行上执行代码李>perl
:保存变量$k=s/(*?,){3}//r
$k
:如果之前没有看到该键,则打印该行如果需要打印$seen{$k}++
perl -aF, -ne'print unless $seen{"@F[3..$#F]"}++' logfile.txt
啊,如果你多喝一杯咖啡,荣耀就全归你了:-)。我喝了五杯,你还是抢了我的风头
:P
如果我没有去喝咖啡休息的话,我可能会更早地读到这个问题:)你在这里做的真是太棒了,哇-你应该得到一个很高的分数,我希望成员们也会投票给我-:)我愚蠢地试图使用数组片作为散列的键。如果日志文件的最后一行没有丢失新行,那么在没有-l
的情况下,它就可以工作。是的,这可以工作。但是,$h{@a[2..4]}
将只使用计数作为键。是的,杰帕尔,我的大脑不喜欢,除非它在段落中,而不是代码中@埃德蒙顿:这是一个简单的sed
式替代。?
使其不贪婪,因此它与大括号中指定的3个以上的文本逗号对不匹配/r
修饰符返回修改后的字符串,而不是修改原始字符串。@jaypal-ah,我明白了,所以?
使前面的重新分段恰好匹配到第一个,
之前,而不是最后一个,
之前。所以写*?,
相当于写[^,]*,
-明白了!/r
这件事也有道理。谢谢。这是一个糟糕的例子,因为所有的记录都是一样的。请说明如何才能有仍然需要过滤掉的不同记录。请查看更新问题,@Maihabunah您仍然需要输出中的3个未引用字段吗?是的,正如问题所问的,我想我会以任何方式协调Ed答案-他有exelent解决方案-:)我喜欢使用-aF,
的切换风格。可能更倾向于-F/,/
,但将这些开关分组到相关开关是传达意图的一个好选择。@Miller:我理解你的偏好,但-F
选项确实不错。如果您使用-Fx
或-F/x/
,则它将为您拆分(/x/,$,0)
。所以-F,
确实拆分(/,/,$,0)
但神奇的是-F/
确实拆分(m[/],$,0)
,所以他们考虑了很多。另外,使用-F/x/
似乎不符合一行程序的整体思想。我非常讨厌它们,但是如果你扔掉严格的
和警告
,为什么还要坚持任何标准呢?@Miller:而且,-aFx
和-Fx
一样,节省了更多的按键做一些自我分析,我认为我对-F//
格式的轻微依恋源于总是试图使用split//
而不是split'
,因此代码本身将表达式作为一种模式而不仅仅是一个文本字符串进行记录。但是,我同意较短的格式有其优点,因此您可能会在我的一些单行代码中不时看到它。:)@米勒:关于split
的第一个参数,我同意你的看法,因为split/
需要不同于split'
。但是后者的命令行等价物是一个简单的-a
,根本没有-F
,因此我认为规则不会转移
perl -aF, -ne'print unless $seen{"@F[3..$#F]"}++' logfile.txt