Unix 查找文本文件中出现最多的单词
我有一个日志文件,记录失败的cat和sub cat名称,并显示错误消息。我的目标是找到最常见的类别 e、 g.日志:Unix 查找文本文件中出现最多的单词,unix,command-line,text-processing,Unix,Command Line,Text Processing,我有一个日志文件,记录失败的cat和sub cat名称,并显示错误消息。我的目标是找到最常见的类别 e、 g.日志: Mon, 26 Nov 2018 07:51:07 +0100 | 164: [ERROR ***] Category ID not found for 'mcat-name1' 'subcat-name1' ref: '073' Mon, 26 Nov 2018 07:51:08 +0100 | 278: [ERROR ***] Category ID not found f
Mon, 26 Nov 2018 07:51:07 +0100 | 164: [ERROR ***] Category ID not found for 'mcat-name1' 'subcat-name1' ref: '073'
Mon, 26 Nov 2018 07:51:08 +0100 | 278: [ERROR ***] Category ID not found for 'mcat-name2' 'subcat-name2' ref: '020'
现在我想确定失败的前10个类别
使用sed:
sed -e 's/\s/\n/g' < file.log | grep ERROR | sort | uniq -c | sort -nr | head -10
您得到了
1636[ERROR
,因为您将空格字符更改为换行符,然后将单词ERROR变灰,然后进行计数
这:
sed -e 's/\s/\n/g' < file.log | grep ERROR
您首先需要grep,然后是sed(非常肯定您可以用sed做得更好,但我只是在谈论命令背后的逻辑):
这可能不是最好的解决方案,因为它会计算单词错误和其他无用的单词,但您没有向我们提供有关输入文件的大量信息。假设
'Bulgari'
是您要提取的类别的一个示例,请尝试
sed -n "s/.*ERROR.*\] Category '\([^']*\)'.*/\1/p" file.log |
sort | uniq -c | sort -rn | head -n 10
sed
命令查找与相当复杂的正则表达式匹配的行并捕获部分行,然后用捕获的子字符串替换匹配项并打印它(-n
选项禁用默认打印操作,因此我们只打印提取的行).剩下的基本上和你已经有的一样
在正则表达式中,我们查找(行的开头后跟)任何内容(新行除外),后跟ERROR
,然后再后跟]Category'
,然后是不包含单引号的字符串,最后是单引号后跟任何内容。为了用单引号中捕获的字符串替换整行,需要大量的“任何内容(新行除外)”。反斜杠括号用于捕获表达式;谷歌的“backref”为完整的独家新闻
您最初的尝试只提取实际的
错误
字符串,因为您用换行符替换了所有周围的空格(模糊地假设您的sed
接受Perl\s
速记,这在sed
中不是标准的,并且\n
在替换中被解释为文字换行符,这也不完全是标准的或可移植的).方法是选择错误的类别,并使用sed
仅用类别名称替换整行
试一试:
sed -e "s/^.* [[]ERROR .*[]] Category '\([^']*\)' .*$/\1/g" file.log | sort | uniq -c | sort -nr | head -16
^
是行的开始
\(…\)
:对于正则表达式中出现的第一对,可以使用\1
引用此转义括号中包含的字符序列;对于第二对,可以使用\2
等
$
是该行的结尾
sed
选择包含[ERROR
和一些字符的行,直到]
,后跟单词Category
,然后在
之后(空格)char,任何字符序列,直到下一个空格char,都用一对转义括号进行选择,后面跟着任何字符序列,直到行尾。如果找到这样一行,它将被替换为类别之后的char序列
您说要使用sed
进行计数,但实际上,您是这样做的整个管道都有sed
、grep
、sort
、uniq
和头
。通常,当这种情况发生时,您的问题是要求awk
:
awk 'BEGIN{FS="\047"; PROCINFO["sorted_in"]="@val_num_asc"}
/\[ERROR /{c[$2]++}
END{for(i in c) { print c[i],i; if(++j == 10) exit } }' file
上述解决方案是GNU awk解决方案,因为它使用了非POSIX兼容的功能,例如数组遍历排序(PROCINFO
)。字段分隔符设置为(”
),它具有八进制值\047
,因为它假定类别名称位于单引号之间
如果您没有使用GNU awk,您可以使用排序
和头
或自己进行排序。一种方法是:
awk 'BEGIN{FS="\047"; n=10 }
/\[ERROR /{ c[$2]++ }
END {
for (l in c) {
for (i=1;i<=n;++i) {
if (c[l] > c[s[i]]) {
for(j=n;j>i;--j) s[j]=s[j-1];
s[i]=l
break
}
}
}
for (i=1;i<=n;++i) {
if (s[i]=="") break
print c[s[i]], s[i]
}
}' file
使用Perl
> cat merlin.txt
Mon, 26 Nov 2018 07:51:07 +0100 | 164: [ERROR ***] Category ID not found for 'mcat-name1' 'subcat-name1' ref: '073'
Mon, 26 Nov 2018 07:51:08 +0100 | 278: [ERROR ***] Category ID not found for 'mcat-name2' 'subcat-name2' ref: '020'
Mon, 26 Nov 2018 07:51:21 +0100 | 1232: [ERROR ***] Category ID not found for 'make' 'model' ref: '228239'
> perl -ne ' { s/(.*)Category.*for(.+)ref.*/\2/g and s/(\047\S+\047)/$kv{$1}++/ge if /ERROR/} END { foreach (sort keys %kv) { print "$_ $kv{$_}\n" } } ' merlin.txt | sort -nr
'subcat-name2' 1
'subcat-name1' 1
'model' 1
'mcat-name2' 1
'mcat-name1' 1
'make' 1
>
请在您的帖子中发布更多关于输入和输出的解释性示例,然后让我们知道,因为它不清楚。同意@RavinderSingh13-您的示例中没有类别1,但您希望它在输出中;同时修复问题标题-似乎您在寻找一些东西,而不是单词本身。当然,
sed
是完美的le也可以执行grep
的工作。See awk似乎是最好的解决方案。结果返回的类别带有一个数字,假设出现的数量,但不会在出现次数最多之后排序。@merlin您有输入文件的示例吗?下面是另一行,在ref number之后有更多的txt。make和model是我所要的尝试计数以识别错误最多的猫:2018年11月26日星期一07:51:21+0100 | 1232:[错误***]找不到“make”“model”ref:'228239'@merlin的类别ID,请您再多提供一行。我们需要您输入的示例。如何向stackoverflow添加文件?awk版本20070501
awk 'BEGIN{FS="\047"; PROCINFO["sorted_in"]="@val_num_asc"}
/\[ERROR /{c[$2]++}
END{for(i in c) { print c[i],i; if(++j == 10) exit } }' file
awk 'BEGIN{FS="\047"; n=10 }
/\[ERROR /{ c[$2]++ }
END {
for (l in c) {
for (i=1;i<=n;++i) {
if (c[l] > c[s[i]]) {
for(j=n;j>i;--j) s[j]=s[j-1];
s[i]=l
break
}
}
}
for (i=1;i<=n;++i) {
if (s[i]=="") break
print c[s[i]], s[i]
}
}' file
awk 'BEGIN{FS="\047"}
/\[ERROR /{c[$2]++}
END{for(i in c) { print c[i],i; if(++j == 10) exit } }' file \
| sort -nr | head -10
> cat merlin.txt
Mon, 26 Nov 2018 07:51:07 +0100 | 164: [ERROR ***] Category ID not found for 'mcat-name1' 'subcat-name1' ref: '073'
Mon, 26 Nov 2018 07:51:08 +0100 | 278: [ERROR ***] Category ID not found for 'mcat-name2' 'subcat-name2' ref: '020'
Mon, 26 Nov 2018 07:51:21 +0100 | 1232: [ERROR ***] Category ID not found for 'make' 'model' ref: '228239'
> perl -ne ' { s/(.*)Category.*for(.+)ref.*/\2/g and s/(\047\S+\047)/$kv{$1}++/ge if /ERROR/} END { foreach (sort keys %kv) { print "$_ $kv{$_}\n" } } ' merlin.txt | sort -nr
'subcat-name2' 1
'subcat-name1' 1
'model' 1
'mcat-name2' 1
'mcat-name1' 1
'make' 1
>