Uma maneira simples é listar todos os arquivos .jpg
, depois remover os nomes base dos arquivos (a parte após a barra final) e remover duplicatas. Você pode usar sed
para remover a parte de cada linha após a barra final. Existe um comando para remover duplicatas, que é chamado de uniq
, mas assume entrada classificada; se você precisar classificar de qualquer maneira, pode deixar sort
fazer a uniquificação.
find ~Mike -iname '*.jpg' | sed 's!/[^/]*$!!' | sort -u >directories_with_jpeg_files.txt
Isso pressupõe que nenhum dos diretórios ou arquivos envolvidos tenham uma nova linha em seu nome. Nomes de arquivos com novas linhas não aparecem em circunstâncias normais, mas tenha cuidado se os nomes de arquivos podem ter sido escolhidos por uma pessoa hostil (por exemplo, se você está processando arquivos que foram enviados para um servidor eo remetente pode escolher o nome do arquivo) .
Se houver diretórios contendo muitos arquivos JPEG e não muitos diretórios que contenham nenhum arquivo JPEG, esse método gasta muito tempo relatando arquivos redundantes. Não é possível dizer ao find para acertar um diretório quando ele encontrar algo nele. Mas você pode restringir a localização para diretórios e dizer para procurar um arquivo JPEG em cada diretório. Isso aumenta o custo para diretórios que não contêm arquivos JPEG, no entanto, pode ter um desempenho ruim se houver muitos diretórios JPEGless.
find ~Mike -type d -exec sh -c '
for d do
set -- "$d/*.[Jj][Pp][Gg]";
if [ -e "$1" ]; then printf %s\n "$d"; fi
done
' sh {} + | sort -u >directories_with_jpeg_files.txt
Como alternativa, em zsh, é possível usar o curinga **
para percorrer diretórios recursivamente, (#i)
para corresponder ao seguinte componente do caminho sem distinção entre maiúsculas e minúsculas para tornar o padrão **/(#i)*.jpg
matching *.jpg
e *.JPG
(e .Jpg
e assim por diante) em uma árvore de diretórios inteira. Adicione o modificador de histórico h
em um qualificador de glob para extrair a parte do diretório. Coloque isso em uma variável de matriz dirs=(…)
e extraia os elementos exclusivos dessa matriz com o sinalizador de expansão do parâmetro u
.
set -o extendedglob # for (#i); best in ~/.zshrc
dirs=(~Mike/**/(#i)*.jpg(:h))
print -lr -- ${(u)dirs} >directories_with_jpeg_files.txt
O equivalente do método de verificação por diretório acima é usar o qualificador e
glob.
print -lr ~Mike/**/*(/e\''set -- $REPLY/*.(#i)jpg(N[1]); (($# != 0))'\') >directories_with_jpeg_files.txt