Por que o curinga * não funciona ao alterar os diretórios?

4

Por exemplo, estou no meu diretório:

/home/myname

e depois quero o CD em um diretório diferente.

/home/pulsar/... 

Como eu preciso ir bem fundo no outro diretório, como posso fazer isso sem precisar digitar a linha inteira? Eu tentei

cd */thedirectoryiwanttogointo

mas isso não funciona. Eu tenho que digitar a linha inteira.

    
por Goldname 07.11.2015 / 05:11

4 respostas

3

Provavelmente seu curinga não funciona porque:

  • não foram encontradas correspondências para o curinga no local que você forneceu ou
  • houve mais de uma correspondência.

A abordagem usual (em um shell) para mover com freqüência entre os subdiretórios é usar o recurso CDPATH , bem como pushd e popd .

O recurso CDPATH (talvez visto pela primeira vez no tcsh) é uma lista de diretórios separados por dois-pontos. Se o pai do seu thedirectoryiwanttogointo name for razoavelmente exclusivo, você poderá adicionar o pai à lista.

Para ler mais (a página de manual do seu shell deve ser a primeira):

pushd e popd são mais recentes que CDPATH , mas ainda datam de meados dos anos 90. Eles permitem que você salve seu diretório atual ("empurrando" para uma pilha) e restaurá-lo ("popping" de uma pilha) durante seus respectivos comandos cd . Para ler mais:

Outras pessoas usam aliases de shell ou links simbólicos. Esses são mais úteis quando se vai a locais bem conhecidos.

    
por 07.11.2015 / 11:46
2

Você deseja que a expansão com curinga encontre um caminho em qualquer parte do sistema. Você pode fazer isso, se você especificar o padrão corretamente:

cd /**/thedirectoryiwanttogointo

funcionará em zsh e fish por padrão, no Bash se você primeiro shopt -s globstar , em tcsh se você tiver set globstar , em ksh93 se você set -o globstar , em yash se você set -o extended-glob .

Isso funciona porque o caractere curinga é usado em um caminho absoluto que começa com / em vez de ser relativo ao diretório atual e, quando você usa o padrão ** , ele se expande para qualquer número de subdiretórios.

Embora isso funcione, é provável que demore muito tempo . Seu shell precisa procurar em todo o seu sistema pelo (s) arquivo (s) correspondente (s). Você pode reduzir isso fornecendo um prefixo maior para aparar mais espaço de pesquisa:

cd /home/pulsar/**/thedirectoryiwanttogointo/

Quanto mais você detalhar, menos busca haverá. Se a árvore de diretórios é bastante esparsa, isso não vai demorar muito e é realmente prático de usar. O / à direita garante que a expansão seja apenas para um diretório, o que remove uma variedade de ambigüidade que pode ocorrer.

Se ainda houver mais de uma correspondência, o resultado dependerá do seu shell. Bash e fish irão mudar para o primeiro jogo em ordem alfabética, ignorando a ambigüidade. tcsh e yash informarão um erro. zsh e ksh irão interpretá-lo como uma tentativa de usar um de seus recursos avançados de troca de diretório e provavelmente reportar um erro.

Se é provável que você use o mesmo diretório repetidamente, coloque o pai. CDPATH ou criar uma variável de shell $FOO que você pode usar no lugar do caminho longo é uma opção melhor. Você pode combinar a variável do shell com a expansão ** para economizar mais digitação se estiver usando isso com frequência.

    
por 07.11.2015 / 20:29
1

Se você está sempre indo para o mesmo diretório, uma solução simples é apenas criar um symlink para ele:

ln -s ~/foo/bar/baz/quux/etc/etc/etc/target ~/shortcut

Se você acessou o diretório anteriormente, outra solução é pesquisar o seu histórico de comandos para o nome que você deseja; pressione ctrl-R e os caracteres procurar por. Isso é bash-específico, mas eu imagino os mais modernos shells tem um mecanismo semelhante.

    
por 07.11.2015 / 10:37
1

Supondo que todos os possíveis diretórios de destino estão em /home e não há caracteres de nova linha em nomes de diretório, você pode usar esta função de shell:

cds() {
    cd "$(find /home -type d -name "$1" | head -n 1)"
}

$ cds thedirectoryiwanttogointo

Naturalmente, dependendo de quantos subdiretórios e arquivos estão em /home e da capacidade de seu sistema operacional armazenar em cache toda a árvore na memória ou não, o desempenho irá variar significativamente.

Nos sistemas GNU, você pode acelerar e tornar mais confiáveis os caracteres de nova linha em nomes de arquivos usando esta sintaxe:

cds() {
    cd "$(find /home -type d -name "$1" -print -quit)"
}

Isso interromperá a pesquisa assim que a primeira correspondência for encontrada.

Note que o argumento é tomado como um padrão, então você pode fazer:

cds 'foo*bar'

por exemplo, para cd no primeiro diretório (o pedido não é especificado), cujo nome começa com foo e termina em bar .

    
por 07.11.2015 / 10:49