grep dentro de una declaración if

grep dentro de una declaración if

Estoy escribiendo una función que solicita el nombre de un archivo y luego me aseguro de que la entrada comience con un carácter alfa; si no es así, volverá a solicitar un nombre al usuario hasta que se cumplan los criterios. También muestra un mensaje adicional si el usuario ingresa una ruta (una ruta es cualquier cosa con un '/' para el propósito de esta asignación). Ahí es donde tengo un problema...

aquí está mi código...

#1) make a getname function that will prompt for filename
function getname(){
trap control_c SIGINT
local fname=$1;

#if there is no input prompt user for file name
if [ ! $1 ]; then
        read -p "Enter a file name: " fname;
fi;

#until grep is given a valid file name
until ( grep -E '^[a-zA-Z_]\w+$' <<< "$fname" > /dev/null 2>&1); do





        #this is were the error is
        if echo "$fname" | grep -E '/';





         then                           #this tests if fname is a file directory
        echo "Paths are not a legal file name.";
        fi;
        read -p "Enter a legal file name: " fname;
done
echo "$fname"
}

La instrucción if dentro del bucle hasta no le indicará al usuario que las rutas no son entradas válidas bajo ninguna circunstancia y tampoco produce errores. ¿Cómo implementaría correctamente un grep en una declaración if?

Respuesta1

De hecho, a mí me funciona en Fedora 26 usando GNU bash, version 4.4.12(1)-release (x86_64-redhat-linux-gnu). La función sigue preguntando si se proporciona la ruta. Vea el resultado.

[@host testing]$ getname
Enter a file name: ab/sav
ab/sav
Paths are not a legal file name.
Enter a legal file name: abc                    
abc
[@host testing]$

Sin embargo, encontré dos pequeños problemas. Primero, imprime la ruta y luego vuelve a solicitar información. Esto se puede resolver usando el interruptor grep -q(q para silencio) en la ifdeclaración (también funciona para until, entonces la redirección de salida ya no es necesaria). En segundo lugar, un solo carácter siempre no es válido en el untilbucle. Esto se puede solucionar cambiando \w+la expresión regular por \w*.

Respuesta2

grepLa declaración in Until es muy voluminosa, puedes simplificarla.

Puedo sugerir este método:

until [ ! -z "$fname" ]; do
        read -p "Enter a legal file name: " fname
        grep -E '^[a-zA-Z_]\w+$' <<< "$fname" > /dev/null 2>&1

        #check exit code
        if [ $? -ne 0 ]; then
                echo "Paths are not a legal file name."
                fname=""
        fi
done

Agregue cualquier condición diferente dentro del bucle hasta si es necesario.

Si desea manejar mensajes para los usuarios, puede usar este truco sin varias readapariciones de comandos:

fname=""
message_for_user="Enter a file name: "

until [ ! -z "$fname" ]; do
        read -p "$message_for_user" fname
        grep -E '^[a-zA-Z_]\w+$' <<< "$fname" > /dev/null 2>&1

        #check exit code
        if [ $? -ne 0 ]; then
                echo "Paths are not a legal file name."
                fname=""
                message_for_user="Enter a legal file name: "
        fi
done

La salida será:

Enter a file name: 1laha
Paths are not a legal file name.
Enter a legal file name:

Tenga en cuenta que la primera y la tercera línea son diferentes.

Respuesta3

Puede utilizar una expresión regular en una ifdeclaración directamente:

if [[ $name  =~ ^[a-zA-Z] ]]

o:

if [[ $name  =~ ^[:alpha:] ]]

información relacionada