Eu gosto de usar find
para isso, já que ele lida bem com nomes de arquivos com caracteres especiais. Você poderia fazer isso com o GNU find
semelhante a como o @Jay sugeriu ou mais portavelmente como
find "$HOME/$dir" -type f -size 0c -exec rm {} +
, que procurará em $HOME/mydir
e todos os subdiretórios. Tudo o que é um arquivo ( -type f
) e tem um tamanho de 0 bytes (-size 0c) terá seu nome aplicado como um argumento para rm
, e deixaremos a linha de comando ter muitos argumentos em vez de invocar rm
para cada arquivo ( +
em vez de \;
a -exec
)
Se você não quiser descer em subdiretórios e quiser que ele seja portável, você pode fazer o seguinte, que eu vou colocar em um subshell para não mudar do diretório atual no shell atual:
( cd "$HOME/$dir"; find . ! -name . -prune -type f -size 0c -exec rm {} + )
Isso usará -prune
para impedir que find
entre nos diretórios adicionais e descartará o diretório .
, o que impedirá que ele faça parte da lista de diretórios que é descendente. Esses dois resultam em find
apenas relatando resultados do diretório atual.
Agora que estamos no diretório atual, podemos revisitar o script que você estava escrevendo, já que estamos muito mais próximos dessa abordagem novamente.
Você deve ter cuidado com a abordagem que estava tentando em seu roteiro. Qualquer arquivo com um caractere em IFS
(como um espaço ou tabulação) faria com que seu loop analisasse nomes parciais de arquivos (por exemplo, se um arquivo fosse chamado with space
, você obteria with
e space
em diferentes iterações). Se você for fazer o loop de arquivos em um diretório, é melhor usar globs como
for f in $HOME/$dir/*; do
if [ -f "$f" ] && [ ! -s "$f" ]; then
printf "It's an empty file: %s" "$f"
fi
done
Esta solução da glob não selecionará nenhum arquivo que comece com .
, a menos que você ative o dotglob.