Como posso classificar um arquivo .txt por duas colunas?

1
Feb  7  domainserver dovecot[37495]: auth(default): od(tjones): lookup failed for user: tjones

Acima está um exemplo de saída do que eu gostaria de classificar. Gostaria de classificar por data na primeira coluna, mas também por tjones à direita, que seria o usuário.

Basicamente, quero todas as instâncias de tjones agrupadas, mas classificadas por data. Eu realmente não tenho idéia do comando a ser usado para fazer isso, ou se eu precisar usar o comando awk para reorganizar as colunas.

Existem, obviamente, mais usuários que tjones , então eu gostaria apenas de classificar por essas duas colunas

Eu tentei o seguinte, mas trouxe um erro "sort: tab multi-character '\ t'"

sort -t '\t' -k1,1 -k5,5n auth_2014uniq.txt > auth_2014uniqtest
    
por user2827773 31.07.2014 / 00:39

2 respostas

2

sort permite a classificação por campos específicos com a -k opção :

sort -k11 -k1,2 data

classificará primeiro pelo campo 11 (nome de usuário) e depois pelos campos 1 e 2 juntos (data). Note que a ordem é importante aqui: classifica pela primeira opção -k e usa a próxima para quebrar os laços (e assim por diante).

Isso é muito dependente da saída exata que você tem lá - cada seqüência de espaços é um separador de campo, então "lookup failed for" é de três campos diferentes.

A edição faz parecer que seus dados reais têm campos separados por tabulações, embora eu não consiga descobrir onde estão as guias nesse caso. Em caso afirmativo, você precisa fornecer uma guia literal, pois o argumento para -t - sort não compreende escapes, e seu shell provavelmente não expande \t . Pressione Ctrl-V Tab para escrever um caractere de tabulação literal ali, ou faça um para substituir: algo como "$(echo -ne '\t')" é uma opção. Se este for o caso, substitua os números de campo apropriados em.

-k5,5n é uma classificação numérica apenas no campo 5, pois nenhum dos seus dados é numérico e parece um erro.

O GNU sort e alguns outros incluem uma extensão de classificação -M mês que você pode usar para colocar meses em ordem. Isso pode ou não estar disponível para você; também está em FreeBSD e OS X , mas não o outro BSDs e não Unices comerciais. Se estiver disponível, -k1,1M -k2,2n classificará as datas pela ordem correta de mês / dia. Observe que também depende da sua localidade: se o arquivo de log e o ambiente usarem uma localização diferente, isso não funcionará. Sem isso, eles serão agrupados por mês e classificados por data em cada mês corretamente.

    
por 31.07.2014 / 00:54
0
sed -n 's/\(.*user: \)\([^ ]*\)$/ /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

OUTPUT

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

Isso remove os dados primeiro, selecionando apenas as linhas que contêm a string user: e copiando o campo a seguir para o início da linha. Então, dados os seguintes dados:

*CRUFT*user: nospaces$

Onde $ representa o fim da linha, a primeira coisa que sed faz é:

nospaces *CRUFT*user: nospaces$

... copie nospaces para o topo da linha. Essa é uma prática comum nesses tipos de operações, porque muitas vezes até uma variação de 1 ou 2 no número de campos em qualquer uma das linhas pode afetar drasticamente o sort . É muito melhor copiar os campos importantes para o início da linha para sort somente . De qualquer forma, é isso que ocorre aqui.

Portanto, sed passa seus dados editados sobre o |pipe to sort , que classifica primeiro no primeiro campo - o nome de usuário - e próximo por MONTH em -k ey combinando o segundo e o terceiro Campos. O resultado é que todas as linhas são agrupadas por nome de usuário e cada agrupamento é classificado por data.

O último sort entrega seus dados de volta para sed sobre outro |pipe e sed retira o primeiro campo da linha - que está lá apenas porque copiou lá no primeiro lugar.

    
por 31.07.2014 / 00:55

Tags