Feb 7 domainserver dovecot[37495]: auth(default): od(tjones): lookup failed for user: tjones
上面是我想要排序的示例输出。我想按第一列的日期排序,但也按tjones
右侧的用户排序。
基本上,我希望所有实例都tjones
分组在一起,但按日期排序。我真的不知道要使用什么命令来执行此操作,或者是否需要使用 awk 命令来重新排列列。
用户显然比 多tjones
,所以我只想按这两列排序
我尝试了以下操作,但出现错误“排序:多字符选项卡‘\t’”
sort -t '\t' -k1,1 -k5,5n auth_2014uniq.txt > auth_2014uniqtest
答案1
sort
允许按特定字段排序-k
选项:
sort -k11 -k1,2 data
将首先按字段 11(用户名)排序,然后按字段 1 和 2 一起排序(日期)。注意顺序很重要这里:它-k
首先按第一个选项排序,然后使用下一个选项来打破平局(依此类推)。
这很大程度上取决于您在那里的确切输出 - 每个空格序列都是一个字段分隔符,因此“查找失败”是三个不同的字段。
编辑使它看起来像您的真实数据具有以制表符分隔的字段,尽管我无法弄清楚在这种情况下制表符在哪里。如果是这样,您需要提供一个文字选项卡作为-t
-的参数,sort
不理解转义,并且您的 shell 可能\t
也不会扩展。要么按Ctrl-VTab在其中写入一个文字制表符,要么用一个制表符来替换:类似的东西"$(echo -ne '\t')"
是一种选择。如果是这种情况,请替换适当的字段编号。
-k5,5n
仅对字段 5 进行数字排序 - 因为您的数据都不是数字,看起来像是一个错误。
GNUsort
和其他一些包括一个月-M
排序扩展,您可以使用它来按顺序排列月份。您可能可以使用,也可以不可以使用;它也在自由BSD和操作系统,但不是其他 BSD而不是商业化的Unices。如果可用,-k1,1M -k2,2n
将按正确的月/日顺序对日期进行排序。请注意,它还取决于您的区域设置:如果您的日志文件和环境使用不同的本地化,则这将不起作用。如果没有这个,它们将按月分组并按每个月内的日期正确排序。
答案2
sed -n 's/\(.*user: \)\([^ ]*\)$/\2 \1\2/p' <<\DATA |\
sort -t' ' -k1,1 -k2,3M |\
sed 's/[^ ]* //'
Feb 7 domainserver dovecot[37495]: auth(default): od(tjones): lookup failed for user: tjones
Feb 8 domainserver dovecot[37495]: auth(default): od(tjones): lookup failed for user: tjones
Feb 5 domainserver dovecot[37495]: auth(default): od(lbones): lookup failed for user: lbones
Jan 7 domainserver dovecot[37495]: auth(default): od(chaz): lookup failed for user: chaz
Mar 7 domainserver dovecot[37495]: auth(default): od(lbones): lookup failed for user: lbones
DATA
输出
Jan 7 domainserver dovecot[37495]: auth(default): od(chaz): lookup failed for user: chaz
Feb 5 domainserver dovecot[37495]: auth(default): od(lbones): lookup failed for user: lbones
Mar 7 domainserver dovecot[37495]: auth(default): od(lbones): lookup failed for user: lbones
Feb 7 domainserver dovecot[37495]: auth(default): od(tjones): lookup failed for user: tjones
Feb 8 domainserver dovecot[37495]: auth(default): od(tjones): lookup failed for user: tjones
这首先通过仅选择包含字符串的行来修剪数据用户:并将以下字段复制到行首。因此,给出以下数据:
*CRUFT*user: nospaces$
其中$
代表行尾,首先sed
要做的是:
nospaces *CRUFT*user: nospaces$
...复制没有空间到队列的头部。这是此类操作中的常见做法,因为通常任何行中字段数量的变化即使是 1 或 2 也会极大地影响sort
.最好将重要字段复制到行的开头,以便sort
仅有的关于那些。无论如何,这就是这里发生的情况。
因此,sed
将编辑后的数据传递给|pipe
to sort
,它首先对第一个字段(用户名)进行排序,然后对MONTH
结合-k
第二个和第三个字段的 ey 进行排序。结果是所有行均按用户名分组,每个分组按日期排序。
最后sort
交出其数据后退覆盖sed
另一个字段|pipe
并sed
删除该行的第一个字段 - 该字段之所以存在,是因为它首先将其复制到那里。