我正在尝试读取一个文件,并按特定字段的出现次数对其进行sorting。 假设我想从日志文件中找出最重复的date,然后使用uniq -c选项并按降序对其进行sorting。 像这样的东西
uniq -c | sort -nr
这会产生这样的输出 –
809 23/Dec/2008:19:20
实际上计数的第一个字段是我的问题….我想从上面的输出得到ony的date,但米无法得到这个。 我试图使用切割命令,并做到了这一点
uniq -c | sort -nr | cut -d' ' -f2
但这只是打印空白…请有人可以帮助我获得date,并砍掉计数。 我只想要
23/Dec/2008:19:20
谢谢
除非计数超过7位数,否则来自uniq
的计数前面是空格,所以您需要执行如下操作:
uniq -c | sort -nr | cut -c 9-
让列(字符位置)9向上。 或者你可以使用sed
:
uniq -c | sort -nr | sed 's/^.\{8\}//'
要么:
uniq -c | sort -nr | sed 's/^ *[0-9]* //'
面对10,000,000或更多的重复计数,这第二个选项是稳健的; 如果你认为这可能是一个问题,它可能比cut
选择更好。 毫无疑问,还有其他的选择。
警告:计数是通过Mac OS X 10.7.3上的实验确定的,但是使用来自coreutils
8.3的GNU uniq
。 BSD uniq -c
在一个数字之前产生了3个前导空格。 POSIX规范说, uniq -c
的输出应该被格式化为:
printf("%d %s", repeat_count, line);
这将不会有任何领先的空白。 考虑到输出格式的这种可能的差异,具有[0-9]
正则表达式的sed
脚本是处理来自uniq -c
观察和理论输出变化的最可靠方法:
uniq -c | sort -nr | sed 's/^ *[0-9]* //'
不要cut -d' ' -f2
,请尝试
awk '{$1="";print}'
也许你需要在开始时删除一个空白:
awk '{$1="";print}' | sed 's/^.//'
或用sed完成,保留原来的空白区域:
sed -r 's/^[^0-9]*[0-9]+//'
另一种解决方案是这样的:
uniq -c | sort -nr | awk '{print $1, $2}'
也可以轻松打印单个字段。
如果你想使用下游的计数字段,下面的命令将把它重新格式化为一个'管道友好'制表符分隔的格式,而不需要填充左边的内容:
.. | sort | uniq -c | sed -r 's/^ +([0-9]+) /\1\t/'
对于原始任务来说,这是一个矫枉过正的问题,但在重新格式化之后,可以使用cut
来删除该字段,正如OP所期望的那样:
.. | sort | uniq -c | sed -r 's/^ +([0-9]+) /\1\t/' | cut -d $'\t' -f2-
将tr -s
添加到管道链中以将多个空间“挤”到一个空格分隔符中:
uniq -c | tr -s ' ' | cut -d ' ' -f3
tr
在一些不起眼的地方非常有用。 不幸的是,它并没有摆脱第一个领先的空间,因此-f3