if [ -z "$(ls -A /path/to/dir)" ]; then
echo "Empty"
else
echo "Not Empty"
fi
Além disso, seria legal verificar se o diretório existe antes.
Eu quero testar se um diretório não contém arquivos. Se assim for, vou pular algum processamento.
Eu tentei o seguinte:
if [ ./* == "./*" ]; then
echo "No new file"
exit 1
fi
Isso dá o seguinte erro:
line 1: [: too many arguments
Existe uma solução / alternativa?
if [ -n "$(find "$DIR_TO_CHECK" -maxdepth 0 -type d -empty 2>/dev/null)" ]; then
echo "Empty directory"
else
echo "Not empty or NOT a directory"
fi
Não há necessidade de contar nada ou globos de casca. Você também pode usar read
em combinação com find
. Se a saída de find
estiver vazia, você retornará false
:
if find /some/dir -mindepth 1 | read; then
echo "dir not empty"
else
echo "dir empty"
fi
Isso deve ser portável.
#!/bin/bash
if [ -d /path/to/dir ]; then
# the directory exists
[ "$(ls -A /path/to/dir)" ] && echo "Not Empty" || echo "Empty"
else
# You could check here if /path/to/dir is a file with [ -f /path/to/dir]
fi
Isso fará o trabalho no diretório de trabalho atual (.):
[ 'ls -1A . | wc -l' -eq 0 ] && echo "Current dir is empty." || echo "Current dir has files (or hidden files) in it."
ou o mesmo comando dividido em três linhas apenas para ser mais legível:
[ 'ls -1A . | wc -l' -eq 0 ] && \
echo "Current dir is empty." || \
echo "Current dir has files (or hidden files) in it."
Basta substituir ls -1A . | wc -l
por ls -1A <target-directory> | wc -l
se você precisar executá-lo em uma pasta de destino diferente.
Editar : substituí -1a
por -1A
(veja o comentário do @Daniel)
Use o seguinte:
count="$( find /path -mindepth 1 -maxdepth 1 | wc -l )"
if [ $count -eq 0 ] ; then
echo "No new file"
exit 1
fi
Dessa forma, você é independente do formato de saída de ls
. -mindepth
ignora o próprio diretório, -maxdepth
impede a defesa recursiva em subdiretórios para acelerar as coisas.
Usando uma matriz:
files=( * .* )
if (( ${#files[@]} == 2 )); then
# contents of files array is (. ..)
echo dir is empty
fi
Uma maneira hacky, mas sem bash, sem PID:
is_empty() {
test -e "$1/"* 2>/dev/null
case $? in
1) return 0 ;;
*) return 1 ;;
esac
}
Isso tira proveito do fato de que test
builtin sai com 2 se receber mais de um argumento depois de -e
: Primeiro, "$1"/*
glob é expandido por bash. Isso resulta em um argumento por arquivo. Então
Se não houver arquivos, o asterisco em test -e "$1"*
não será
expandir, então o Shell volta a tentar o arquivo chamado *
, que retorna
1.
... exceto se realmente houver um arquivo chamado exatamente *
, então o
asterisco se expande para bem, asterisco, que termina como a mesma chamada
acima, ie. test -e "dir/*"
, só que desta vez retorna 0. (Obrigado @TrueY
para apontar isso.)
Se houver um arquivo, test -e "dir/file"
é executado, o que retorna 0.
Mas se houver mais arquivos que 1, test -e "dir/file1" "dir/file2"
é executado, que o bash reporta como erro de uso, ou seja, 2.
case
envolve toda a lógica, de modo que apenas o primeiro caso, com 1 status de saída, seja relatado como sucesso.
Possíveis problemas que não verifiquei:
Existem mais arquivos do que o número de argumentos permitidos - acho que isso poderia se comportar de forma semelhante ao caso com 2+ arquivos.
Ou existe um ficheiro com um nome vazio - não tenho a certeza se é possível em qualquer sano OS / FS.
Acho que a melhor solução é:
files=$(shopt -s nullglob; shopt -s dotglob; echo /MYPATH/*)
[[ "$files" ]] || echo "dir empty"
graças ao link
Esta é uma edição anônima da minha resposta que pode ou não ser útil para alguém: Uma ligeira alteração indica o número de arquivos:
files=$(shopt -s nullglob dotglob; s=(MYPATH/*); echo ${s[*]})
echo "MYPATH contains $files files"
Isso funcionará corretamente mesmo que os nomes de arquivos contenham espaços.
if find "${DIR}" -prune ! -empty -exit 1; then
echo Empty
else
echo Not Empty
fi
EDITAR: Eu acho que esta solução funciona bem com o gnu find, depois de um rápido olhar para o implementação . Mas isso pode não funcionar, por exemplo, com achado do netbsd . De fato, aquele usa o campo st_size do stat (2). O manual descreve-o como:
st_size The size of the file in bytes. The meaning of the size
reported for a directory is file system dependent.
Some file systems (e.g. FFS) return the total size used
for the directory metadata, possibly including free
slots; others (notably ZFS) return the number of
entries in the directory. Some may also return other
things or always report zero.
Uma solução melhor, também mais simples, é:
if find "${DIR}" -mindepth 1 -exit 1; then
echo Empty
else
echo Not Empty
fi
Além disso, o -prune na primeira solução é inútil.
EDIT: no -exit para o gnu find .. a solução acima é boa para o find do NetBSD. Para o GNU encontrar, isso deve funcionar:
if [ -z "'find \"${DIR}\" -mindepth 1 -exec echo notempty \; -quit'" ]; then
echo Empty
else
echo Not Empty
fi
Com FIND (1) (no Linux e no FreeBSD) você pode olhar de maneira não recursiva em uma entrada de diretório via "-maxdepth 0" e testar se está vazio com "-empty". Aplicado à pergunta que isso dá:
if test -n "$(find ./ -maxdepth 0 -empty)" ; then
echo "No new file"
exit 1
fi
Tudo isso é ótimo - basta transformá-lo em um script para que eu possa verificar diretórios vazios abaixo do atual. O abaixo deve ser colocado em um arquivo chamado 'findempty', colocado no caminho em algum lugar para que o bash possa encontrá-lo e, em seguida, o chmod 755 para ser executado. Pode ser facilmente alterado para suas necessidades específicas, eu acho.
#!/bin/bash
if [ "$#" == "0" ]; then
find . -maxdepth 1 -type d -exec findempty "{}" \;
exit
fi
COUNT='ls -1A "$*" | wc -l'
if [ "$COUNT" == "0" ]; then
echo "$* : $COUNT"
fi
Este trabalho para mim, para verificar & processa arquivos no diretório ../IN
, considerando que o script está no diretório ../Script
:
FileTotalCount=0
for file in ../IN/*; do
FileTotalCount='expr $FileTotalCount + 1'
done
if test "$file" = "../IN/*"
then
echo "EXITING: NO files available for processing in ../IN directory. "
exit
else
echo "Starting Process: Found ""$FileTotalCount"" files in ../IN directory for processing."
# Rest of the Code
Que tal testar se o diretório existe e não está vazio em uma declaração if
if [[ -d path/to/dir && -n "$(ls -A path/to/dir)" ]]; then
echo "directory exists"
else
echo "directory doesn't exist"
fi
Para qualquer diretório diferente do atual, você pode verificar se está vazio tentando rmdir
, porque rmdir
tem a garantia de falhar em diretórios não vazios. Se rmdir
for bem-sucedido e você realmente quiser que o diretório vazio sobreviva ao teste, apenas mkdir
novamente.
Não use este hack se houver outros processos que possam se tornar desconcertados por um diretório que eles sabem sobre deixar de existir brevemente.
Se rmdir
não funcionar para você e você estiver testando diretórios que poderiam conter um grande número de arquivos, qualquer solução que dependesse de globalização de shell poderia ficar lenta e / ou entrar em limites de comprimento de linha de comando. Provavelmente, é melhor usar find
nesse caso. A solução find
mais rápida que consigo pensar é como
is_empty() {
test -z $(find "$1" -mindepth 1 -printf X -quit)
}
Isso funciona para as versões GNU e BSD de find
, mas não para o Solaris, que está faltando a cada um desses operadores find
. Ame seu trabalho, Oracle.
Você pode tentar remover o diretório e aguardar um erro; rmdir não excluirá o diretório se não estiver vazio.
_path="some/path"
if rmdir $_path >/dev/null 2>&1; then
mkdir $_path # create it again
echo "Empty"
else
echo "Not empty or doesn't exist"
fi
Tags bash