如何按两列对 .txt 文件进行排序?

如何按两列对 .txt 文件进行排序?
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将编辑后的数据传递给|pipeto sort,它首先对第一个字段(用户名)进行排序,然后对MONTH结合-k第二个和第三个字段的 ey 进行排序。结果是所有行均按用户名分组,每个分组按日期排序。

最后sort交出其数据后退覆盖sed另一个字段|pipesed删除该行的第一个字段 - 该字段之所以存在,是因为它首先将其复制到那里。

相关内容