Bash CD até em determinada pasta

13

Eu faço muito trabalho no Magento, assim como muitas pessoas com quem trabalho, e é chato ter que digitar:

cd ../../../../../../

Para encontrar apenas alguns diretórios da pasta raiz "httpdocs", estou tentando criar um script que siga este pseudo-código:

while lowest level directory != httpdocs
    cd ../
end while;

Parece bem simples, suponho que teria que fazer algum tipo de grep para verificar se a última parte do diretório de trabalho atual é httpdocs, se não continuar subindo até que seja verdade.

Eu estive olhando para aprender bash para isso, embora pareça que tem que haver algo lá fora, que é semelhante, e a sintaxe me intriga sem fim.

    
por user652650 03.06.2011 / 06:48

5 respostas

7

Isso tem que ser uma função de shell , não um script, porque um script é executado em um novo shell (e, portanto, não pode mudar o diretório do shell original).

function cdroot()
{
  while [[ $PWD != '/' && ${PWD##*/} != 'httpdocs' ]]; do cd ..; done
}

Você pode, é claro, nomear a função como quiser.

Algumas explicações: O primeiro teste ( $PWD != '/' ) é um teste de segurança, caso você use cdroot quando não estiver em uma pasta httpdocs. Parará quando você chegar à raiz.

O segundo teste ( ${PWD##*/} != 'httpdocs' ) é um pouco mais complicado. $PWD é uma variável que contém o caminho do diretório atual. ${PWD##*/} apara tudo até e incluindo a última barra.

    
por 03.06.2011 / 07:05
25

Eu tenho uma função chamada upto no meu .bashrc que permite que você vá até qualquer diretório no caminho atual pelo nome:

upto ()
{
    if [ -z "$1" ]; then
        return
    fi
    local upto=$1
    cd "${PWD/\/$upto\/*//$upto}"
}

Eu também tenho conclusão para esta função, para que ela me dê nomes de diretório válidos e conclusão quando eu clicar em tab:

_upto()
{
    local cur=${COMP_WORDS[COMP_CWORD]}
    local d=${PWD//\//\ }
    COMPREPLY=( $( compgen -W "$d" -- "$cur" ) )
}
complete -F _upto upto

Além disso, tenho outra função jd que me permite ir para qualquer diretório abaixo do atual:

jd(){
    if [ -z "$1" ]; then
        echo "Usage: jd [directory]";
        return 1
    else
        cd **"/$1"
    fi
}

Exemplo:

[/www/public_html/animals/hippopotamus/habitat/swamps/images] $ upto h[TAB][TAB]
habitat       hippopotamus
[/www/public_html/animals/hippopotamus/habitat/swamps/images] $ upto hippopotamus
[/www/public_html/animals/hippopotamus] $ jd images
[/www/public_html/animals/hippopotamus/habitat/swamps/images] $ 
    
por 03.06.2011 / 10:29
5

A função bash mais simples que você pode colocar no seu .bashrc que eu posso pensar (simples porque não usa loops ou processos externos) é:

cdup() {
    cd "${PWD/\/httpdocs\/*//httpdocs}"
}

Isso usa a expansão do parâmetro substituição de padrões para substituir tudo depois de /httpdocs/ in $PWD com '/ httpdocs'. Parece muito confuso, porque temos que escapar das barras no caminho para diferenciá-las das barras na sintaxe de expansão do bash. Além disso, não escape de barras na sequência de substituição, por isso também parece inconsistente.

Se não houver /httpdocs/ no caminho atual, nenhuma substituição será executada e apenas será alterada para o diretório atual.

Por exemplo, a substituição substituirá /a/b/c/httpdocs/e/f/g por /a/b/c/httpdocs e cd nesse diretório.

A função precisa estar em seu ambiente shell atual (como função ou alias), pois um processo filho não pode alterar o diretório atual de seu pai. É por isso que eu digo para colocá-lo em seu .bashrc e não em um script de shell.

    
por 03.06.2011 / 09:53
3

Você também pode colocar algo assim em seu perfil:

alias cdh='cd $(echo $PWD | sed -e "s/\(.*\/httpdocs\)\/.*//")'

Digitar cdh levará você ao diretório mais alto httpdocs em seu caminho atual.

    
por 03.06.2011 / 07:29
2

Ele não resolve completamente o seu problema, mas economizará fazendo cd ../../../../../../ um pouco. Eu pedi emprestado isso do usuário desconhecido da postagem here .

up N

pula os diretórios N para cima na árvore de diretórios

Em vez de digitar

cd ../../../..

você acabou de digitar

up 4

e um

cd -    

vai trazer você de volta

Coloque a função no seu .bashrc para usá-la.

# (c) 2007 stefan w. GPLv3          
function up {
ups=""
for i in $(seq 1 $1)
do
        ups=$ups"../"
done
cd $ups
}
    
por 03.06.2011 / 07:22