Cómo encontrar/corregir un error en una ruta

Cómo encontrar/corregir un error en una ruta

Es frecuente que una ruta larga esté mal escrita o que en una entrada del archivo de registro no exista una ruta. ¿Existe un comando o función de shell que navegue por la jerarquía de rutas hasta que encuentre una ruta coincidente?

El intercambio de línea de comando podría ser así:

$ ls /var/lib/my/supper/complicated/path
File or directory not found
$ fixpath /var/lib/my/supper/complicated/path
Found /var/lib/my

Como característica adicional, una detección de similitudes sería excelente:

$ fixpath /var/lib/my/supper/complicated/path
Found /var/lib/my
Did you mean /var/lib/my/super/complicated/path

Respuesta1

 $ fixpath /home/user/docus/collection/unix/djakl/jfkdsl/dfjksld/fsdkl
Found /home/user/docus/collection/unix
 $ type fixpath
fixpath is a function
fixpath ()
{
    CURDIR="$PWD";
    DIR="$1";
    E=1;
    while [ $E -eq 1 ]; do
        cd "$DIR" 2> /dev/null && {
            E=0;
            echo Found "$DIR"
        } || {
            DIR="${DIR%/*}";
            DIR="${DIR:-/}"
        };
    done;
    cd "$CURDIR"
}

La autocorrección de similitudes que la mayoría de los shells modernos pueden realizar por sí mismos. Al menos bash y zsh lo hacen.

Respuesta2

La siguiente función de shell toma un nombre de ruta y determina el bit más largo que realmente existe. Para ello, elimina el último elemento de la ruta hasta que la ruta esté completamente vacía o corresponda a un archivo (o directorio, o cualquier cosa) que realmente exista.

fixpath () (
    pathname="$1"

    while [ -n "$pathname" ] && [ ! -e "$pathname" ]; do
        pathname=${pathname%/*}
        case "$pathname" in
            */*) continue ;;
            *) [ -e "$pathname" ] || pathname=''
               break
        esac
    done

    printf 'Longest existing path in "%s" is "%s"\n' "$1" "$pathname"
)

La casedeclaración es necesaria para terminar el bucle en el caso de que $pathnameno contenga a /(lo que significa que no se modificará mediante la sustitución de variables). Esto evita un bucle infinito en algunas circunstancias.

Probándolo:

$ fixpath /home/kk/blaha/123
Longest existing path in "/home/kk/blaha/123" is "/home/kk"

$ fixpath "$HOME/.profile"
Longest existing path in "/home/kk/.profile" is "/home/kk/.profile"

$ fixpath "n"
Longest existing path in "n" is ""

información relacionada