classifica a saída ls pelos usuários

3

No Linux, existe uma maneira de classificar ls output por usuários ? O que eu tento alcançar é algo assim:

user_ a arquivo1
user_ a arquivo2
user_ b another_file
user_ c this_file
user_ c that_file
user_ d file3

Estou ciente de que uma listagem como essa também conteria tamanho de arquivo, permissões etc. - minha principal preocupação é a classificação pelos usuários. Seria bastante útil, não seria

Até agora, encontrei ls -l | sort -k 3 para classificar por coluna três, que [se usar ls -l ] contém o proprietário do arquivo [assim sort -k 4 para classificar por grupo].

MAS e se o proprietário do arquivo não estiver na linha três? Existe outra maneira de conseguir isso, independente do número da coluna ?

Atualização : esqueci de mencionar que eu trabalho no BASH e tento manter isso por um bom tempo daqui em diante, para que as coisas não se tornem mais complicadas.

    
por erch 18.04.2013 / 19:10

6 respostas

3

Determinar em qual coluna o nome do proprietário está em uma única saída de ls -l sem saber qual é o que não é possível. Você poderia tentar corresponder as entradas em cada coluna com o arquivo passwd , mas não há garantia de que você não corresponderia à coluna do grupo ou à coluna do nome do arquivo, as quais poderiam conter apenas nomes encontrados em /etc/passwd .

Se você quiser ir com ls , poderá executar o programa duas vezes, uma vez como ls -l e uma vez como ls -g . O último descarta o proprietário, portanto, combinando as linhas com base nas outras informações, você seria capaz de determinar o nome do proprietário sem especificação. Este não é um exercício que eu ficaria feliz em fazer em um script de shell bash.

    
por 18.04.2013 / 19:37
3

Com zsh , você pode definir ordens de classificação e usá-las em qualificadores de globbing, como:

zmodload zsh/stat
uid() zstat -A REPLY +uid -- $REPLY

... *(no+uid)

( n para ordem numérica, o para ordem , +uid para pedir com a função uid ). A idéia é ter uma função que tenha um nome de arquivo em $REPLY e retorne algo em $REPLY que zsh ordena.

Então, por exemplo, com o GNU ls :

ls -ldU -- *(no+uid)

Com as ferramentas somente GNU, o equivalente seria algo como:

find . ! -name . -prune -printf '%U\t%p
zmodload zsh/stat
uid() zstat -A REPLY +uid -- $REPLY

... *(no+uid)
' | sort -zn | tr '
ls -ldU -- *(no+uid)
\n' '\n
find . ! -name . -prune -printf '%U\t%p%pre%' |
  sort -zn |
  tr '%pre%\n' '\n%pre%' |
  cut -f2- |
  tr '%pre%\n' '\n%pre%' |
  xargs -r0 ls -ldU
' | cut -f2- | tr '%pre%\n' '\n%pre%' | xargs -r0 ls -ldU
    
por 18.04.2013 / 19:27
3

Não analise ls : use stat

stat -c "%U %n" -- * | sort
    
por 18.04.2013 / 20:38
2

Como o OP não estipula requisitos particulares de portabilidade (além do uso no Bash), e como analisando o ls parece continua sendo a abordagem popular, e como a solução stat não parece lidar com novas linhas em nomes de arquivos melhor (quem coloca novas linhas em nomes de arquivos, afinal?), vou lançar minha própria sugestão para os mais elegantes solução:

Eu acredito que o OP realmente teve quase a melhor resposta. Apenas precisa ser escapado para evitar o comportamento inesperado do aliasing (lembre-se, esta é uma solução específica do Bash):

\ls -l | sort -k 3

18 caracteres, requer apenas ls e sort e não há loops. Elegante, fácil de entender e confiável.

Além disso, como Olivier apontou em sua resposta, pode ser desejável limitar sort apenas à terceira coluna, em vez de toda a linha que começa com essa coluna:

\ls -l | sort -k 3,3

Retratarei esta resposta se alguém puder encontrar uma implementação de ls -l que não contenha o proprietário na terceira coluna ou uma maneira de quebrar essa solução que não quebra as soluções dadas em outras respostas.

    
por 19.04.2013 / 17:59
1

1) Determine qual coluna é o nome:

myls='ls -al'
echo '+' > /tmp/MYOWNFILE.$$  #so file will be of size 2, "+" and newline.
zeuser=$( $myls /tmp/MYOWNFILE.$$ | awk -v myname=$(whoami) '{ for (field=1;field<=NF;field++) { if ($field == myname) { print field ; break } } }' )
zesize=$( $myls /tmp/MYOWNFILE.$$ | awk '{ for (field=1;field<=NF;field++) { if ($field == 2) { print field ; break } } }' )
zename=$( $myls /tmp/MYOWNFILE.$$ | awk -v filename=/tmp/MYOWNFILE.$$ '{ for (field=1;field<=NF;field++) { if ($field == filename) { print field ; break } } }' )
rm /tmp/MYOWNFILE.$$

Ele coloca na variável zeuser a coluna mostrando o nome de usuário
Eu também determino zesize = column segurando o tamanho, e zename = coluna segurando o nome do arquivo

Vou colocar o comando ls em uma variável, então as linhas que determinam a coluna estão usando o comando real usado mais tarde (caso você o altere e altere a (s) coluna (s) listada (s))

2) use a classificação para classificar nessa coluna:

$myls | sort -k${zeuser},${zeuser}  #sort ONLY on column of usernames (see last example for bad alternative)
$myls | sort -k${zeuser},${zeuser} -k${zename},${zename} #sort on user, and then on filename
$myls | sort -k${zeuser},${zeuser} -k${zesize},${zesize}nr #sort on user, 
                            #  and then on size 
                            #modifiers: 'n'=order Numerically (and not alphabetically), 
                            #           'r'=Reverse order
$myls | sort -k${zeuser}    #sort STARTING FROM user column, which is probably not what you want!
                     #indeed the next column is probably the group, then the size...
                     #It will be sorting in a not so usefull way (especially as the
                     #  size will be sorted alphabetically instead of numerically)
    
por 18.04.2013 / 21:16
0

Aqui está um pequeno folheto que deve ser feito para você:

\ls -l | sort -k$(for i in {1..5}; do field=$(\ls -ld ~ | cut -d' ' -f$i); if [ x$field = x$(whoami) ]; then echo $i; break; fi; done)

Estou percorrendo cada campo em um ls -l realizado em seu diretório pessoal até encontrar o campo que corresponde ao seu nome de usuário e substituindo esse número por para ir com a opção -k para sort .

Eu não sou muito especialista, então algumas delas podem ser uma versão bash ou específica do GNU, mas funciona bem na minha máquina.

Eu escolhi de 1 a 5 porque isso deve ser o mais importante que você precisa para encontrar o usuário. Você poderia usar mais números, especialmente se salvasse a saída de ls -ld ~ em uma string em vez de chamar todas as vezes, e provavelmente poderia otimizar ainda mais se armazenasse os resultados em uma matriz e fizesse referência a ela dessa maneira. Mas isso foi um rápido e sujo, fora do topo da minha cabeça, uma vez uso tipo de resposta.

    
por 18.04.2013 / 20:00