Nomes de arquivo podem usar qualquer caractere, exceto o caractere nul (
) e barra, que é um separador de caminho. Variáveis podem conter quaisquer dados (exceto caracteres nul na maioria dos shells). Se devidamente citados, os nomes de arquivos podem ser armazenados com segurança em variáveis e usados com utilitários. find
Em relação aos seus pontos:
Para iterar sobre um conjunto de arquivos (arquivos ou diretórios regulares), você pode usar um loop de shell simples como
for name in ./*; do
# some code that uses "$name"
done
Para iterar arquivos durante a seleção de arquivos específicos usando critérios específicos, N
é a melhor opção. por exemplo, para selecionar todos os arquivos regulares no diretório atual (ou abaixo) que sejam mais antigos que N
dias (tenha data de modificação pelo menos -size
dias no passado):
find . -type f -mtime +N
Da mesma forma, -name
é usado para selecionar arquivos com base no tamanho e *.mov
para corresponder ao nome do arquivo em um padrão de globbing.
Por exemplo, para selecionar os arquivos regulares que possuem nomes de arquivos que correspondem a $HOME/Movies
e que foram modificados na última semana:
find . -type f -name '*.mov' -mtime -7
Então, realmente faça algo com esses arquivos, como movê-los para o diretório {}
:
find . -type f -name '*.mov' -mtime -7 -exec mv {} "$HOME/Movies" ';'
O mv
será substituído pelo nome do caminho do arquivo na invocação de {}
. Você não precisa citar o find
(ele não mudará nada se você o fizer), pois find
não invocará a divisão de palavras ou a expansão de nome de arquivo do shell no nome do caminho.
Uma melhoria adicional para isso seria detectar colisões de nomes de arquivos no diretório de destino. Para isso, usamos um script de ajuda curto, que terá vários nomes de arquivos em sua linha de comando:
destdir="$HOME/Movies"
for name do
if [ -f "$destdir/${name##*/}" ]; then
printf "%s already exists in %s, not overwriting it!\n" "${name##*/}" "$destdir" >&2
else
mv "$name" "$destdir"
fi
done
ou, em formato de atalho:
destdir="$HOME/Movies"
for name do
[ -f "$destdir/${name##*/}" ] && printf "skipping %s\n" "$name" >&2 && continue
mv "$name" "$destdir"
done
Conectando isso ao nosso comando %code% :
find . -type f -name '*.mov' -mtime -7 -exec sh -c '
destdir="$HOME/Movies"
for name do
[ -f "$destdir/${name##*/}" ] && printf "skipping %s\n" "$name" >&2 && continue
mv "$name" "$destdir"
done' sh {} +
Em nenhum lugar ao longo do caminho, permitimos que o shell faça a divisão de palavras ou a globalização de nomes de arquivo no nome do caminho ou no nome do arquivo que estamos processando no momento.
Para mais informações:
- Por que o looping é uma má prática de saída? um>
- Implicações de segurança de esquecendo de citar uma variável em shells bash / POSIX
- Por que minha script de shell sufocar no espaço em branco ou outros caracteres especiais?
- Por que * não * analisar 'ls'?
- É possível usar 'localizar -exec sh -c 'com segurança?