Como encontrar/corrigir erros em um caminho

Como encontrar/corrigir erros em um caminho

Muitas vezes, um caminho longo é digitado incorretamente ou você recebe uma entrada no arquivo de log informando que o caminho não existe. Existe um comando ou função shell que navega na hierarquia de caminhos até encontrar um caminho correspondente?

A troca de linha de comando poderia ser assim:

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

Como recurso bônus, uma detecção de similaridade seria ótima:

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

Responder1

 $ 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"
}

A autocorreção de similaridade que a maioria dos shells modernos pode fazer sozinha. Pelo menos bash e zsh fazem.

Responder2

A função shell a seguir recebe um nome de caminho e determina o bit mais longo que realmente existe. Ele faz isso removendo o último elemento do caminho até que o caminho esteja completamente vazio ou corresponda a um arquivo (ou diretório, ou qualquer coisa) 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"
)

A caseinstrução é necessária para encerrar o loop no caso que $pathnamenão contém a /(o que significa que não seria modificado pela substituição da variável). Isso evita um loop infinito em algumas circunstâncias.

Testando:

$ 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 ""

informação relacionada