Imprimir original de quem comando

3

Eu quero mostrar aos usuários on-line usando o comando who , mas quero ter uma saída única e não mostrar duplicatas. Eu canalizei a saída para awk , mas eu não estou muito familiarizado com isso, este é o caminho certo e como proceder?

    
por Phil_Charly 08.12.2013 / 19:21

3 respostas

4

É mais fácil apenas fazer isso com sort :

 who | sort -u -k1,1

O sinalizador -u solicita linhas "exclusivas" (suprime duplicatas). O sinalizador de chave ( -k ) diz para considerar apenas a primeira palavra em cada linha para fins de classificação e exclusividade.

    
por 08.12.2013 / 19:26
4

Usando o AWK

who | awk '!x[$1]++'

Quebra de Comando :

x[$1] é um array associativo em um array cujo índice é uma string. Todos os arrays no AWK são associativos. Nesse caso, o índice na matriz é o primeiro campo do comando "who", que é o nome de usuário. Se o usuário é repetido, o loop principal incrementa a contagem por usuário executando efetivamente.

What is the meaning of the preceding ! sign?

O operador NOT é excludente - exclui o nome de usuário que já está em matriz associativa.

    
por 08.12.2013 / 20:44
2

A resposta de alexis é provavelmente a que você quer. É simples, curto e funciona. Mas, no interesse de mostrar que há muitas maneiras de esfolar um gato, eu gostaria de apresentar uma alternativa:

who | awk '{print $1}' | uniq

Isso usa o awk para imprimir apenas o primeiro token de who , o nome de usuário e, em seguida, uniq para mesclar entradas repetidas. Há um problema com isso: uniq apenas mescla termos repetidos consecutivos . No meu laptop eu sou a única pessoa que usa a máquina, mas se eu executar who -a para mostrar todas as coisas extras, como processos de login em execução em todos os ttys, nem todas as instâncias do meu usuário são listadas uma após a outra . Portanto, a lista de who precisa ser classificada. Se adicionarmos outro pipe ao comando:

who | sort | awk '{print $1}' | uniq

Isso deve fazer o truque.

É claro que neste momento estamos usando quatro programas para alcançar o que a alexis já fez com dois. Além disso, não estamos nem mesmo evitando usar o programa sort que a alexis usou. Se quisermos ter um método alternativo que seja realmente uma alternativa, não podemos usar o tipo. Vamos tentar usar apenas o awk, como o pôster original parecia estar tentando fazer:

who | awk '
{
   array[$1]=$1
}
END{
   for(i in array) {
      print array[i]
   }
}
'

Esse pequeno fragmento de awk coloca todos os nomes de usuários em um array em um local indexado pelo próprio nome de usuário. Isso garante que, se um nome de usuário aparecer duas vezes, ele substituirá o mesmo nome de usuário que já estava nesse ponto. Em seguida, ele imprime todas as entradas da matriz, que é uma lista exclusiva de todos os nomes de usuários. Para economizar espaço, poderíamos colocá-lo em uma linha:

who | awk '{array[$1]=$1} END {for(i in array) {print array[i]}}'

Isso está ficando um pouco longo, mas poderia usar mais uma coisa: os nomes realmente deveriam ser classificados. Vamos executar o array por meio de uma classificação de inserção para que a saída seja um pouco mais previsível:

who | awk '
{
   # Read the usernames into an associative array
   array[$1]=$1
}
END{
   # Put the usernames into an indexed array and note the length
   len = 1
   for(j in array) {
      indexed[len] = array[j]
      ++len
   }

   # Sort the array
   for (i=2; i < len; ++i) {
      for (j=i; indexed[j-1] > indexed[j]; --j) {
            temp = indexed[j]
            indexed[j] = indexed[j-1]
            indexed[j-1] = temp
      }
   }

   # Print the unique usernames in order
   for(i=1; i< len; ++i) {
      print indexed[i]
   }
}
'

Isso lê os nomes de usuários como antes, mas antes de imprimi-los, nós os movemos para uma matriz indexada e classificamos essa matriz indexada. A saída será apenas os nomes de usuários (nenhuma das informações extras de who ), classificados, sem duplicatas. Algo parecido com isto:

Betty
John
Ziggy
albert
james
nicola


Agora, você pode afirmar que alexis e Rahul forneceram respostas de uma linha, no entanto, não há nada que impeça você de escrever isso em uma linha:

who | awk '{array[$1]=$1} END {len = 1; for(j in array) {indexed[len] = array[j]; ++len} for (i=2; i < len; ++i) { for (j=i; indexed[j-1] > indexed[j]; --j) {temp = indexed[j]; indexed[j] = indexed[j-1]; indexed[j-1] = temp }} for(i=1; i< len; ++i) {print indexed[i]}}'

Espero que ajude.

    
por 08.12.2013 / 21:54

Tags