Solución:
Esto es sorprendentemente complicado de hacer bien.
Fundamentalmente, -d
solo probará un único argumento, incluso si pudiera hacer coincidir los nombres de archivo usando una expresión regular.
Una forma sería darle la vuelta al problema y probar los directorios para una coincidencia de expresiones regulares en lugar de probar la coincidencia de expresiones regulares para los directorios. En otras palabras, haz un bucle todos los directorios en $HOME
usando un simple globo de shell, y pruebe cada uno contra su expresión regular, rompiendo en una coincidencia, finalmente probando si el BASH_REMATCH
la matriz no está vacía:
#!/bin/bash
for d in "$HOME"/*/; do
if [[ $d =~ (ana|mini)conda[0-9]? ]]; then
break;
fi
done
if ((${#BASH_REMATCH[@]} > 0)); then
echo "anaconda/miniconda directory is found in your $HOME"
else
echo "anaconda/miniconda is not found in your $HOME"
fi
Una forma alternativa sería usar un glob de shell extendido en lugar de la expresión regular y capturar cualquier coincidencia de glob en una matriz. Luego pruebe si la matriz no está vacía:
#!/bin/bash
shopt -s extglob nullglob
dirs=( "$HOME"/@(ana|mini)conda?([0-9])/ )
if (( ${#dirs[@]} > 0 )); then
echo "anaconda/miniconda directory is found in your $HOME"
else
echo "anaconda/miniconda is not found in your $HOME"
fi
El final /
asegura que solo los directorios coincidan; los nullglob
evita que el shell devuelva la cadena no coincidente en el caso de cero coincidencias.
Para hacer recursivo, establezca el globstar
opción de shell (shopt -s globstar
) y luego respectivamente: –
-
(versión de expresiones regulares):
for d in "$HOME"/**/; do
-
(versión glob extendida):
dirs=( "$HOME"/**/@(ana|mini)conda?([0-9])/ )
De hecho, como ya se mencionó, esto es complicado. Mi enfoque es el siguiente:
- usar
find
y es regex capacidades para encontrar los directorios en cuestión. - dejar
find
imprimir unx
para cada directorio encontrado - almacenar el
x
es en una cadena - si la cadena no está vacía, entonces se encontró uno de los directorios.
Por lo tanto:
xString=$(find $HOME -maxdepth 1
-type d
-regextype egrep
-regex "$HOME/(ana|mini)conda[0-9]?"
-printf 'x');
if [ -n "$xString" ]; then
echo "found one of the directories";
else
echo "no match.";
fi
Explicación:
-
find $HOME -maxdepth 1
encuentra todo debajo$HOME
pero restringe la búsqueda a un nivel (es decir: no recurre a subdirectorios). -
-type d
restringe la búsqueda a solod
irectorios -
-regextype egrep
dicefind
que tipo de expresión regular nos ocupamos de. Esto es necesario porque cosas como[0-9]?
y(…|…)
son algo especiales yfind
no los reconoce por defecto. -
-regex "$HOME/(ana|mini)conda[0-9]?"
es el real
expresión regular queremos estar atentos -
-printf 'x'
solo imprime unx
para cada cosa
que cumpla las condiciones anteriores.
Puede recorrer una lista de nombres de directorio que desea probar y actuar en consecuencia si existe uno de ellos:
a=0
for i in {ana,mini}conda{,2}; do
if [ -d "$i" ]; then
unset a
break
fi
done
echo "anaconda/miniconda directory is ${a+not }found in your $HOME"
Obviamente, esta solución no permite la potencia completa de expresiones regulares, pero la expansión de shell globbing y brace es igual al menos en el caso que mostró. El bucle sale tan pronto como existe un directorio y desarma la variable configurada previamente a
. En el siguiente echo
línea, la expansión del parámetro ${a+not }
se expande a la nada si a
está establecido (= no se encontró ningún directorio) y “no” más.