Encontre arquivos em vários nomes de pastas

44

Eu estou tentando lista de todos os arquivos dir1, dir2, dir3e dir4que pode ser em qualquer lugar como um sub-diretório do meu cwdusando o findcomando. Eu tentei o seguinte sem sucesso:

find . -type f -regextype posix-egrep -regex 'dir1/.+|dir2/.+|dir3/.+|dir4/.+'

Eu tentei posix-extendedtambém. Como posso listar esses arquivos?

Aaron
fonte
encontrar . -type f -regextype sed -regex ". * / dir [1-4] / [a-z0-9] *" .. resposta mais curta até agora :) veja a resposta abaixo .. unix.stackexchange.com/a/390333 / 242983
alpha_989 4/17

Respostas:

59

E se você quiser procurar três pastas com o nome foo, bare bazpara todos os *.pyarquivos, use este comando:

find foo bar baz -name "*.py"

então, se você deseja exibir arquivos de dir1 dir2 dir3usofind dir1 dir2 dir3 -type f

tente isso find . \( -name "dir1" -o -name "dir2" \) -exec ls '{}' \;

harish.venkat
fonte
Eu deveria ter esclarecido. Talvez eu não tenha o caminho para os arquivos que desejo pesquisar. Eu só sei que eles são subdiretórios do diretório atual.
Aaron
use em ./dirvez dedir
harish.venkat
O diretório ainda precisa estar no cwd, porém, pode ser dois níveis mais baixo (por exemplo ./path/to/dir1), caso em ./dir1que não existiria.
Aaron
editou a resposta.
harish.venkat
8

É melhor usar a diretiva -path:

find .  \( -type f -and -path '*/dir1/*' -or -path '*/dir2/*' -or -path '*/dir3/*' -or -path '*/dir4/*' \)

O que significa: encontre todos os arquivos no diretório atual, onde há 'dir1' ou 'dir2' ou 'dir3' ou 'dir4' no caminho.

Manutenção periódica
fonte
Você tem os parênteses no lugar errado. Veja também -ae -opara o equivalente padrão de GNU's -and/ -or.
Stéphane Chazelas
4

Apenas para que todos saibam. A adição de .*/antes de cada um dirresolveu o problema, pois ele regexcorresponde ao caminho completo que parece.

Aaron
fonte
3

Esta é a minha primeira ideia depois de ler as respostas anteriores:

find . -type f -regextype posix-egrep -regex ".*/(dir1|dir2|dir3|dir4)/.+"

Isso leva em consideração que a regex deve corresponder ao nome do arquivo inteiro e é mais fácil entender.

Ronin Tom
fonte
2

Amostra de localização rápida (!) De arquivos específicos (access_log) em vários locais definidos por curinga (diretório inicial) e diretório de log geral do apache2, aplicando também a filtragem de nomes para excluir logs ssl e logs antigos compactados com gzip. Não responde diretamente à pergunta aqui, mas pode ser útil para alguém que encontrou essas instruções (como eu).

find / \( -path "*var/log/apache2*" -o -path "*home/*/logs*" \) -type f  -name "*access_log" ! -name "*ssl*"

Tenha cuidado com os espaços, especialmente perto de \(e \).

A propósito, eu o usei no apachetop, para encontrar os sites mais ativos no meu servidor.

apachetop -d1 -s9 -p $(find / \( -path "*var/log/apache2*" -o -path "*home/*/logs*" \) -type f  -name "*access_log" ! -name "*ssl*" -print | sed 's/^/-f '/)
Kristjan Adojaan
fonte
2

você não precisa especificar dir1 para dir4 pelo nome, se estiver usando regextype

find . -type f -regextype sed -regex ".*/dir[1-4]/[^/]*"
  • type f: encontre arquivos e não diretórios
  • regextype sed: usa sed regextype
  • regex: pesquisa usando regex em todo o caminho
  • ".*/dir[1-4]/[a-z0-9]*":. * no início significa qualquer número de caracteres que possam ser do tipo (caractere / número / barra invertida (/) etc); dir [1-4] significa procurar por "dir" seguido de um número entre 1 e 4; / [^ /] * afirma que o seguinte diretório1-4 omite os nomes de caminho que possuem / neles, portanto, ele retorna apenas arquivos no diretório dir1-dir4 e ignora os subdiretórios que possam estar no diretório dir1-dir4.

criou um diretório para você testá-lo: https://github.com/alphaCTzo7G/stackexchange/tree/master/linux/findSolution04092017

alpha_989
fonte
(1) Talvez nunca saibamos a situação ou os requisitos exatos de Aaron, mas outras respostas tomaram a decisão prudente de que ele possui quatro diretórios, cujos nomes não são especificados. (Eles poderiam ser red, green, bluee yellow, ou poderiam ser John, Paul, Georgee Ringo.) A sua resposta assume que eles são , literalmente dir1 , dir2, dir3e dir4. ... (continua)
Scott
(Continua)… (2) Por que você acha que Aaron não deseja pesquisar subdiretórios? Ele parece estar dizendo que sim. (3) Por que você está restringindo a pesquisa para arquivos cujos nomes conter apenas letras e algarismos minúsculas (excluindo coisas como foo_bar, foo.txte FOO)? (4) Por que seu texto explica /[^/]*quando sua resposta não o utiliza?
Scott Scott
Oi Scott, isso é para o seu comentário.
Alpha_989 4/17
(1-3). ele menciona "Estou tentando listar todos os arquivos de dir1, dir2, dir3 e dir4 " que podem estar em qualquer lugar como um subdiretório do meu cwd , o que significa que dir1-dir4 pode estar em qualquer lugar, mas ele deseja encontrar o arquivo certo dentro de dir1-dir4. é claro, se não for dir1-dir4, você deve alterá-lo para nomes específicos usando vermelho \ | azul \ | verde \ | etc ..
alpha_989 4/17
4. erro de digitação lá .. Eu usei [a-z0-9] * antes .. então percebi [^ /] * é mais curto e mais inclusivo .. esqueci de mudar quando publiquei isso. Obrigado por seus comentários cuidadosos.
Alpha_989 4/17
0

Eu sei que você especificou que usando find, mas apenas para mostrar outras opções que podem ser usadas, você pode usar xargs:

find . -type d | grep -E "dir1$|dir2$" | xargs ls  

find . -name "dir1" -or -name "dir2" | xargs ls

Você pode ter um arquivo chamado "pastas" que contenha algo como:

$ cat folders
dir1
dir2
dir3
dir4

Então, você pode fazer algo assim:

$ cat folders | xargs -I % find . -type d -name % | xargs ls
./Documents/dir1:
file1  file2  file3  file4

./Documents/dir2:
file1  file2  file3  file4

./Documents/dir3:
file1  file2  file3  file4

./Documents/dir4:
file1  file2  file3  file4

xargs na minha opinião, me sinto mais versátil do que encontrar -exec. Além disso, você pode fazer algumas coisas loucas como

$ cat << EOF | xargs -I {} find ~ -name "{}" | xargs ls
> dir1
> dir2
> dir3
> EOF
/home/user/Documents/dir1:
file1  file2  file3  file4

/home/user/Documents/dir2:
file1  file2  file3  file4

/home/user/Documents/dir3:
file1  file2  file3  file4
Cuauhtli
fonte