Dados dois padrões, procure diretórios específicos e imprima os últimos três nomes de arquivos que correspondem a cada padrão

4

Como posso reduzir esse comando? O objetivo é exibir os 3 arquivos mais recentes que estão na pasta ABC e corresponder uvw no nome do arquivo e, em seguida, fazer o mesmo, mas corresponder xyz no nome do arquivo.

Estou procurando encurtar isso, pois é necessário adicionar mais strings para procurar no futuro.

find . -name 'ABC' | xargs ls | grep -i uvw |sort| tail -n 3; find . -name 'ABC' | xargs ls | grep -i xyz |sort| tail -n 3

Exemplo de saída:

2018-06-23T01-23-56.919Z-UVW.gz
2018-06-23T01-29-56.556Z-UVW.gz
2018-06-23T23-26-14.463Z-UVW.gz
2018-08-08T00-16-22.923Z-xyz.js
2018-08-08T00-16-24.517Z-xyz.js
2018-08-08T00-16-25.427Z-xyz.js
    
por kouichi 08.08.2018 / 20:18

4 respostas

4

com zsh :

set -o extendedglob # best in ~/.zshrc
for w (uvw xyz) printf '%s\n' **/ABC/(#i)*$w*(D[-3,-1]:t)
  • **/ : qualquer nível de subdiretórios
  • (#i) : correspondência insensível a maiúsculas e minúsculas para o que segue
  • (D[-3,-1]:t) : qualificador glob
  • D : inclua arquivos ocultos e procure dentro de diretórios ocultos, como find
  • [-3,-1] : selecione apenas os últimos 3 (os globs são classificados em ordem lexical por padrão)
  • :t : modificador que extrai o final do caminho do arquivo (basename) como seu ls faz.

Observe que, se houver vários diretórios ABC, o nome desses diretórios influenciará a classificação (os arquivos em a/ABC aparecerão antes daqueles em b/ABC ).

    
por 08.08.2018 / 21:00
2

Isso irá procurar por arquivos que correspondam a qualquer desses fragmentos:

for fragment in ABC UVW xyz; do 
    find . -name "\*${fragment}\*" | sort | tail -n3; 
done

Se você quiser encontrar arquivos que correspondam a todos deles, você pode fazer algo assim:

find . -name '*ABC*' -a -name '*xyz*' | sort | tail -n3

-a é o operador booleano AND de find .

Para o BSD find , use -or e -and em vez de -o e -a .

    
por 08.08.2018 / 20:26
2

Provavelmente você está procurando

find . -iregex '.*/ABC/[^/]*uvw.*' | sort | tail -n3

Veja como funciona:

  • -iregex pesquisa no modo insensitivo
  • .*/ABC/ olha em qualquer profundidade para o diretório ABC (o nome completo do diretório)
  • [^/]*uvw.* o nome de dir ABC é seguido diretamente por um nome de arquivo contendo uvw string, não quaisquer subdiretórios entre

As partes sort e tail não foram alteradas.

Quanto à adição de outros padrões: você precisa fazer um loop sobre este comando com todas as strings necessárias, ou se você precisa apenas de 3 arquivos, independentemente do grupo que eles estão chegando, você pode combinar tudo em um comando:

find . -iregex '.*/ABC/[^/]*\(uvw\|xyz\)[^/]*' | sort | tail -n3
    
por 08.08.2018 / 21:17
1

Eu consegui o que eu precisava com loops for em um script bash, é possível fazer isso na linha de comando?

#!/bin/bash
for i in ABC DEF
do
  for j in uvw xyz
  do
    x='find . -iname $i | xargs ls | grep -i $j | sort | tail -n 3'
    echo "$x"
  done
done
    
por 09.08.2018 / 01:10