Classifique a saída de find -exec ls

14

É possível a saída find … -exec ls -ls ;ordenada alfabeticamente, por nome de arquivo?

Este é o meu comando cron:

find /home/setefgge/public_html -type f -ctime -1 -exec ls -ls {} \;

Este comando funciona bem, na maior parte. Mas os resultados não são classificados em nenhuma sequência significativa. Seria muito útil se eles fossem classificados pelo campo de nome do arquivo.

MaJ
fonte
1
Usando o zsh? ls -ls **/*(.)
Kevin
@ Kevin Não é bem assim - lsiria classificar.
Gilles 'SO- stop be evil'

Respostas:

14

Presumo que seus nomes de arquivos não contenham novas linhas.

find /home/setefgge/public_html -type f -ctime -1 -exec ls -nls {} + | sort -k 10

Usar em +vez de ;para finalizar a -execação a torna mais rápida, agrupando as chamadas de ls. Você pode classificar através do sortcomando; diga para começar a classificar no 10º campo (os 9 primeiros são os metadados: blocos, permissões, contagem de links, usuário, grupo, tamanho e 3 campos de data / hora). A opção -ninforma lspara usar valores numéricos para o usuário e grupo, o que evita o risco de nomes de usuários ou grupos que contenham espaços em branco.

Como alternativa, com o zsh, você pode sair sem assumir nenhum nome usando qualificadores glob para coletar e classificar os arquivos e zargsexecutar lsvárias vezes se a linha de comando for muito longa. Você precisa do GNU ls(especificamente sua -fopção) para evitar a re-classificação ls(outra abordagem seria emular lscom o zsh zstat).

autoload -U zargs
zargs -- /home/setefgge/public_html/**/*(.c-2) -- ls -lnsf
Gilles 'SO- parar de ser mau'
fonte
Muito obrigado! O uso do primeiro comando que você enviou faz a classificação. O número ainda seria 10 se eu usasse um caminho mais curto? Por exemplo, se eu executar o mesmo comando em / home / setefgge em vez de em public_html?
MAJ
@MaJ 10 é o número de campos ignorados, não tem nada a ver com o tamanho do nome do arquivo.
Gilles 'SO- stop be evil'
Obrigado. Agradeço sua ajuda e também a ajuda de todos os demais. Eu considero esse problema resolvido. Meu comando cron agora está classificando os arquivos. Esta é a primeira vez que enviei uma pergunta ao Stackexchange. Não vejo a opção "Resolvido". Se algum de vocês souber como postar isso como resolvido, vá em frente e faça isso. Obrigado!
MAJ
@MaJ A coisa mais próxima de marcar uma pergunta como resolvida é marcar uma das respostas como aceita. Somente você, o solicitante, pode fazê-lo. Para fazer isso, clique na marca de seleção ao lado da resposta que mais lhe ajudou. Se você aceitar uma resposta, receberá mais 2 pontos de reputação e, depois disso, poderá votar novamente nas postagens; você pode votar todas as postagens que achou úteis. Para obter mais informações, consulte a página do tour e a página de ajuda sobre o que fazer quando alguém responder à sua pergunta .
Gilles 'SO- stop be evil'
1

Por que não canalizar o resultado da busca através da classificação e depois executar ls para cada uma das linhas?

find . -type f -ctime -1 | sort | while IFS= read -r filename; do ls -ls "$filename"; done
groxxda
fonte
1

O POSIX tem a dizer sobre datas em uma ls -llistagem ong:

O <date and time>campo deve conter a data e o carimbo de data e hora apropriados de quando o arquivo foi modificado pela última vez. No código do idioma POSIX, o campo deve ser equivalente à saída do seguinte comando date:

date "+%b %e %H:%M"

... se o arquivo foi modificado nos últimos seis meses ou:

date "+%b %e %Y"

Levando isso em consideração e assegurando que, se houver novas linhas em um nome de arquivo, elas sejam devidamente preenchidas com a ls -qopção também especificada no POSIX , é relativamente fácil preparar uma regex para um lsresultado sem find:

d=$(date "+%b %e") y=$(date --date=yesterday "+%b %e")
echo "$d" "$y"

###OUTPUT###
Jul  5 Jul  4

greppara isso e você retornará apenas linhas que contenham as seqüências que representam as datas de hoje ou de ontem. O seguinte comando adiciona um pouco a isso:

ls -alRcq | sed "1H;/^-/!{/./d;N;h};/$d\|$y/!d;x;/\n/p;g"

ls opções consistem em:

  1. -a retornar todos os arquivos em um diretório - incluindo aqueles que começam com um .dot
  2. -l lista longa
  3. -R listar recursivamente todos os diretórios filhos
  4. -c tempo de modificação da tela em vez do tempo de acesso
  5. -qretorna o shell glob em ?vez de caracteres não imprimíveis ou \tab em um nome de arquivo

Esses resultados são passados ​​sobre o |pipearquivo ao sedqual corresponde apenas:

  1. A linha em branco que precede o nome do caminho e a seguinte linha
  2. Linhas começando com - (em outras palavras - não dpara diretório) que também contêm o seu date.
  3. No entanto, ele não imprime as linhas do nome do caminho, a menos que o diretório que eles nomeiem contenha arquivos para os quais você filtrou.

A saída é assim:

ls -alRcq --color=always | 
sed "1H;/^-/!{/./d;N;h};/$d\|$y/!d;x;/\n/p;g"

###OUTPUT###
.:
-rw------- 1 mikeserv mikeserv   2086 Jul  4 10:52 .bash_history
-rw------- 1 mikeserv mikeserv   2657 Jul  4 15:20 .lesshst
-rw-r--r-- 1 mikeserv mikeserv    681 Jul  5 05:18 .zdirs
-rw------- 1 mikeserv mikeserv 750583 Jul  5 08:28 .zsh_history
-rw-r--r-- 1 mikeserv mikeserv    166 Jul  4 23:02 Terminology.log
-rw-r--r-- 1 mikeserv mikeserv 433568 Jul  4 13:34 shot-2014-06-22_17-10-16.jpg
-rw-r--r-- 1 mikeserv mikeserv 445192 Jul  4 13:34 shot-2014-06-22_17-11-06.jpg

./.cache/efreet:
-rw------- 1 mikeserv mikeserv  37325 Jul  4 22:51 desktop_localhost_C.eet
-rw------- 1 mikeserv mikeserv  37325 Jul  4 23:30 desktop_localhost_en_US.eet
-rw------- 1 mikeserv mikeserv  24090 Jul  4 22:51 desktop_util_localhost_C.eet
-rw------- 1 mikeserv mikeserv  24090 Jul  4 23:30 desktop_util_localhost_en_US.eet
-rw------- 1 mikeserv mikeserv  16037 Jul  4 23:30 icon_themes_localhost.eet
-rw------- 1 mikeserv mikeserv   3117 Jul  4 23:30 icons___efreet_fallback_localhost.eet
-rw------- 1 mikeserv mikeserv 768039 Jul  4 23:30 icons_gnome_localhost.eet
-rw------- 1 mikeserv mikeserv  18589 Jul  4 23:30 icons_hicolor_localhost.eet

./.config:
-rw-r--r-- 1 mikeserv mikeserv   30 Jul  4 19:10 pavucontrol.ini

./.config/chrome:
-rw-r--r-- 1 mikeserv mikeserv 94332179 Jul  4 13:36 conf.tar.lz4.bak

Sim, ele ainda funciona com LS_COLORS- o que provavelmente é uma baixa prioridade para o seu croncurso, mas, ei, suas opções estão abertas.

De qualquer forma, isso oferece algumas vantagens significativas em relação a outras soluções possíveis.

  1. Em primeiro lugar, o find+ lsenvolve várias invocações - isso envolve apenas um único lsprocesso, e é por isso que ele é capaz de classificar tudo de maneira confiável - o que faz por padrão - e sorttambém é tornado auxiliar.

  2. Qualquer solução que envolva finde sorte lsestá praticamente fazendo tudo do trabalho duas vezes. lse findambos resolverão todos os nomes de caminhos e statarquivos. lse sortambos classificarão todos os resultados. Provavelmente é melhor usar apenas o single ls.

  3. Então, naturalmente, há o datee sedpartes desta resposta. O importante é notar que você faz a parte mais difícil e obtém o regex primeiro - e apenas uma vez - e depois remove apenas uma única lista de resultados, em vez de dizer, obter resultados, obter resultados, classificar resultados e classificar resultados.

  4. Isso não quebra nos nomes de arquivos que contêm novas linhas, como provavelmente outras soluções. Essa solução tem suas próprias advertências - que explico a seguir -, mas são minuciosas e fáceis de manusear. Na minha opinião, esta é a solução mais robusta aqui.

Há dois casos em que o comando acima pode causar problemas. O primeiro envolve os ?globs nos nomes de arquivos - enquanto já é uma solução mais robusta do que qualquer outro oferecido aqui, e a probabilidade de você encontrar um ?é pequena o suficiente por si só, existe a possibilidade de resolver esses globs pode corresponder a mais de um nome de arquivo. Por favor, veja isto para mais informações sobre este assunto.

A outra possibilidade envolve um falso positivo - por exemplo, se você tiver um nome de arquivo que realmente corresponda à datestring pela qual estamos pesquisando, grepmas que não foi realmente modificada em nenhum desses dias. Não estou contando que isso seja um problema, mas, se for, pergunte sobre isso e provavelmente posso ajudá-lo a tornar o regex mais específico para lidar com isso.

mikeserv
fonte
0

Você pode realmente usar uma combinação de find, xargs e ls.

Aqui está um comando de amostra: find . -type f -print0 | xargs -0 ls -lt

  • find procurará recursivamente todos os arquivos no diretório atual.
  • O xargs passará essa lista de arquivos para o lscomando em uma única chamada (desde que findretorne menos que os ARG_MAXarquivos).
  • ls -lt classificará esses arquivos por hora e formatará a saída

Para recuperar seu sistema, ARG_MAXvocê pode digitar:

$ getconf ARG_MAX
> 2621440
Máx.
fonte
-1
ls -l $(find /home/setefgge/public_html -type f -ctime -1 | sort)
Walter A
fonte
1
lsfaz sua própria classificação, assim canalizando a saída do findmeio sorté inútil. Além disso, seu comando gerencia nomes de arquivos que contêm espaços em branco (entre outros) e falhará se houver muitos nomes de arquivos.
Gilles 'SO- stop be evil'