Lista todos os arquivos que terminam em um conjunto de caracteres em todos os subdiretórios que não terminam no conjunto de caracteres

3

Como você listaria arquivos que terminam em x, y ou z em sub-diretórios que NÃO TERMINAM em x, y ou z ?

    
por SpdTolas 12.08.2016 / 09:40

2 respostas

2

Para evitar a descida em *[xyz] e para arquivos regulares na profundidade 2 (encontre a/x , mas não ax/x nem a/b nem x e não olhe além de dois diretórios como a/b/x ), POSIXly:

LC_ALL=C find . \( ! -name '*[xyz]' -o -prune \) \
  -path './*/*' -prune -type f -name '*[xyz]'

Isso seria o equivalente de:

printf '%s\n' *[!xzy]/*[xyz]

Só que ele também procuraria dentro de diretórios ocultos e por arquivos ocultos e não procuraria links simbólicos para diretórios e procuraria somente por arquivos regulares.

Se você quiser procurar *[xyz] arquivos regulares em qualquer profundidade, desde que o diretório pai direto não termine em xyz (assim, encontrar x , a/x , a/b/x , x/b/x , mas não x/x nem a/x/x ), com GNU find :

LC_ALL=C find . -regex '.*[^xyz]/[^/]*[xyz]' -type f

com zsh :

setopt extended_glob
printf '%s\n' **/*[xzy]~*[xyz]/[^/]#(D.)

POSIXly:

LC_ALL=C find . -name '*[xzy]' -type f -exec sh -c '
  for f do
    case ${f%/*} in
      *[xzy]) ;;
      *) printf '%s\n' "$f"
    esac
  done' sh {} +

Se você não quer olhar para dentro de *[xyz] , mesmo em subdiretórios, (isto é, se você não quer encontrar x/a/x ) então é só:

find . -name '*[xyz]' -prune -type f

-prune diz find para não descer no diretório (e retornar true).

Ou com zsh :

setopt extended_glob
printf '%s\n' (*[^xyz]/)#*[xyz](D.)
    
por 12.08.2016 / 12:03
1

1

Somente para arquivos nos subdiretórios all , em qualquer profundidade:

(depois de Stéphane Chazelas)

 find . -name '*[xyz]' -prune -type f

2

Para apenas arquivos em subdiretórios na profundidade 2, tente isto:

(Inclui opções fora do padrão. Ainda não me sinto bem em omití-las com um entendimento nada trivial. Para detalhes, veja os comentários.)

find . -mindepth 2 -maxdepth '2' -wholename "./*[^xyz]/*[xyz]" -type f 2>/dev/null

find procura por arquivos

. informa ao find para iniciar no diretório atual

-mindepth 2 significa que a pesquisa deve começar em um nível mais profundo que o diretório atual

-maxdepth 2 significa que a pesquisa deve terminar 1 nível mais profundo que o diretório atual

-wholename define o valor do caminho do arquivo ./*[^xyz]/*[xyz] é o que você definiu na sua pergunta

-type f informa ao encontrar para procurar apenas por arquivos

2>/dev/null informa para não imprimir mensagens de erro

3

Se você quiser não apenas arquivos, mas também direcórios, isso é mais fácil:

ls -d *[^xyz]/*[xyz]

ls é para listar arquivos e diretórios

ls -d é ls com a opção -d , que não mostra o que há nos diretórios

UPDATE

i am just curious as to how you change the search criteria to the end of the file name instead of including the file extension. So the search would show filez.abc instead of file.abz

Isso fornece uma listagem no diretório atual:

ls -d *[xyz].???

Nos arquivos do Linux, não há extensões como você as imagina. A extensão é uma parte do nome do arquivo. Reescrevendo todos os comandos anteriores é um pouco complicado, especialmente o primeiro.

1.

(O melhor que eu já vi até agora)

find . -path '.*[^xyz]/*[xyz].???' -type f | grep -v [xyz]/

2.

find . -mindepth 2 -maxdepth '2' -wholename "./*[^xyz]/*[xyz].???" -type f 2>/dev/null

3.

ls -d *[^xyz]/*[xyz].???
    
por 12.08.2016 / 10:43

Tags