He escrito un pequeño script bash para encontrar si un directorio llamado anacondao minicondaen mi usuario $HOME. Pero no encuentra el miniconda2directorio en mi casa.
¿Cómo podría solucionar esto?
if [ -d "$HOME"/"(ana|mini)conda[0-9]?" ]; then
    echo "miniconda directory is found in your $HOME"
else
    echo "anaconda/miniconda is not found in your $HOME"
fi
PD: si lo tengo [ -d "$HOME"/miniconda2 ]; then, entonces encuentra el directorio miniconda2, así que creo que el error radica en la parte"(ana|mini)conda[0-9]?"
Quiero que el guión sea general. Para mí, es miniconda2, pero para algún otro usuario podría ser anaconda2, miniconda3, etc.
                    
                        command-line
                                bash
                                scripts
                                
                    
                    
                        Jenny
fuente
                
                fuente

Respuestas:
Esto es algo sorprendentemente complicado de hacer bien.
Básicamente,
-dsolo probará un único argumento, incluso si puede hacer coincidir los nombres de archivo con una expresión regular.Una forma sería darle la vuelta al problema y probar directorios para una coincidencia de expresiones regulares en lugar de probar la coincidencia de expresiones regulares para directorios. En otras palabras, recorra todos los directorios
$HOMEcon un simple glob de shell y pruebe cada uno contra su expresión regular, rompiendo una coincidencia y finalmente probando si laBASH_REMATCHmatriz no está vacía:Una forma alternativa sería utilizar un globo de caparazón extendido en lugar de la expresión regular y capturar cualquier coincidencia de globo en una matriz. Luego pruebe si la matriz no está vacía:
El seguimiento
/garantiza que solo los directorios coincidan; lanullglobevita que la cáscara de regresar la cadena sin igual en el caso de los partidos cero.Para hacer que sea recursivo, configure la
globstaropción de shell (shopt -s globstar) y luego respectivamente: -(versión regex):
for d in "$HOME"/**/; do(versión glob extendida):
dirs=( "$HOME"/**/@(ana|mini)conda?([0-9])/ )fuente
?([0-9])en lugar de@(|[0-9]):?(...)coincide con cero o uno, igual que el?cuantificador de expresiones regulares .~/{ana,mini}conda{0..9}*/minioanacondase instala en$HOME/sub-directories? Por ejemplo$HOME/sub-dir1/sub-dir2/miniconda2globstarDe hecho, como ya se mencionó, esto es complicado. Mi enfoque es el siguiente:
findy sus capacidades de expresiones regulares para encontrar los directorios en cuestión.findimprimir unxpara cada directorio encontradoxes en una cadenaAsí:
Explicación:
find $HOME -maxdepth 1encuentra todo a continuación,$HOMEpero restringe la búsqueda a un nivel (es decir, no se repite en subdirectorios).-type drestringe la búsqueda a solodirectorios-regextype egrepdice confindqué tipo de expresión regular tratamos. Esto es necesario porque cosas como[0-9]?y(…|…)son algo especiales yfindno las reconoce por defecto.-regex "$HOME/(ana|mini)conda[0-9]?"es la expresión regular real que queremos buscar-printf 'x'solo imprime unxpor cada cosa que satisfaga las condiciones anteriores.fuente
-bash: -regex: command not found found one of the directoriesprintfPor ejemplo, cuando ejecuto el script, funciona bien, pero no encuentra el comando printf cuando no hay coincidencia, pero creo que es porque no hay nada que imprimir.-bash: -printf: command not found no match.-printfno es un comando sino un argumento parafind. Eso es lo que hace la barra invertida al final de la línea anterior.-quitdespués de imprimir la ruta encontrada, a menos que quiera seguir detectando ambigüedad.xen su lugar:foundDir=$(find $HOME -maxdepth 1 -type d -regextype egrep -regex "$HOME/(ana|mini)conda[0-9]?" -print -quit); echo "found $foundDir"Puede recorrer una lista de nombres de directorio que desea probar y actuar si existe uno de ellos:
Obviamente, esta solución no permite la potencia de expresión regular completa, pero la expansión del refuerzo de caparazón y la abrazadera es igual al menos en el caso que usted mostró. El bucle sale tan pronto como existe un directorio y desarma la variable establecida previamente
a. En laecholínea siguiente , la expansión del parámetro se${a+not }expande a nada siase establece (= no se encuentra el directorio) y "no" más.fuente
Posible solución es buscar miniconda y anaconda por separado como se muestra a continuación
Pero si alguien tiene sugerencias, me gustaría saber por qué no podemos pasar una expresión regular cuando buscamos directorios.
fuente
shopt -s nullglob; dirs=( "$HOME"/miniconda* "$HOME"/anaconda* ); if (( ${#dirs[@]} > 0 )); then ...] || [con el-oque al menos no debería romperse si se encuentran ambos directorios ya que ambos globos de directorio se buscan en la misma prueba.