Você está tornando isso muito mais complicado do que o necessário. Você não parece querer recorrer a subdiretórios, então tudo que você precisa para encontrar esses diretórios que não possuem um arquivo específico é:
for dir in */; do [ ! -e "$dir"/"$filename" ] || printf '%s\n' "$dir"; done
E para ver quais deles têm outro arquivo:
for dir in */; do
[ ! -e "$dir"/"$filename1" ] &&
[ -e "$dir"/"$filename2" ] &&
printf '%s\n' "$dir";
done
Ou, em uma sintaxe ligeiramente mais clara:
for dir in */; do
if [ ! -e "$dir"/"$filename1" ]; then
if [ -e "$dir"/"$filename2" ]; then
printf '%s\n' "$dir";
fi
fi
done
Tudo isso é feito usando as ferramentas internas do shell. Especificamente:
-
[
: this, e os]
associados são sinônimos para otest
construído (vejahelp [
ouhelp test
se estiver usando um shell sh-style). São formas de escrever operações de teste no shell. -
-e
: testa se existe um arquivo / diretório, etc. Vejahelp test
. O formato simples é:[ -e file ]
, que retornará verdadeiro sefile
existir. -
[ ! -e filename ]
: o!
simplesmente inverte o teste. Portanto,[ ! -e file ]
será verdadeiro sefile
não existir.
Juntos, isso significa que o comando acima faz:
## Iterate over every directory (dirs only because of the '/' in '*/')
## saving each of them in the variable $dir.
for dir in */; do
## If this $dir does not contain $filename1
if [ ! -e "$dir"/"$filename1" ]; then
## If this $dir does contain $filename2
if [ -e "$dir"/"$filename2" ]; then
## Print the directory name
printf '%s\n' "$dir";
fi
fi
done
Para executar isso, é claro, primeiro é necessário definir $filename1
e $filename2
de acordo. Por exemplo:
filename1="unwantedFile"
filename2="wantedFile"