Utilisation de cd pour monter plusieurs niveaux de répertoire

39

J'ai affaire à des projets java qui aboutissent souvent à des dossiers profondément imbriqués (/ chemin / vers / projet / com / java / lang / peu importe, etc.) et veulent parfois pouvoir sauter, disons, 4 niveaux de répertoire vers le haut. Taper cd ../../../ .. est pénible et je ne veux pas créer de lien symbolique. Y a-t-il un drapeau sur cd qui vous permet de monter plusieurs niveaux de répertoire (dans ma tête, ce serait quelque chose comme cd -u 4)? Malheureusement, je ne trouve aucune page de manuel pour le cd en particulier, au lieu d'obtenir simplement la page inutile "intégrée".

Tossrock
la source
1
Modification de bash pour interpréter cd ...où le nombre de '.' serait le nombre de niveaux à monter. Est-ce que cela provoquerait un conflit dont je ne suis pas au courant?
Pour ceux qui viennent ici pour MacOS, vous pouvez installer zshet Oh My Zshqui est une meilleure alternative à bash, puis vous pouvez simplement faire cd ...(plusieurs points) comme il se doit
Dominic

Réponses:

29

Ou ... essayez ceci: (yay Google)

Naviguez dans le répertoire en utilisant ..n:

Dans l'exemple ci-dessous, ..4 est utilisé pour monter le niveau de répertoire 4, ..3 pour monter le niveau de répertoire 3, ..2 pour monter le niveau de répertoire 2.

Ajoutez l'alias suivant au .bash_profile et reconnectez-vous.

alias .. = "cd .."

alias ..2 = "cd ../ .."

alias ..3 = "cd ../../ .."

(etc)

Voir Hack # 2

cutrightjm
la source
10
Je préfère utiliser les alias .., ...et ....comme ils sont plus rapides à taper, mais le principe des alias est le même bien sûr.
Bernhard
1
@bernhard Vous êtes le bienvenu, car je ne pense pas que cela provoquerait des conflits. Je l'ai laissé tel quel parce que je l'ai cité sur le site Web.
cutrightjm
Le shell 4DOS.EXE pour DOS était également pris en charge cd ..., cd ....etc. C'était très pratique.
Alexios
..... n'est pas plus rapide que ..4, en fait il est 2 caractères plus lent ..
Ryan
29

Une fonction simple, avec un alias aussi:

function cd_up() {
  cd $(printf "%0.s../" $(seq 1 $1 ));
}
alias 'cd..'='cd_up'

(Vous pouvez le définir ~/.bashrcsi vous le souhaitez dans chaque cas).

C'est simple à utiliser:

$ cd.. 10
Grigory K
la source
Joli! Travaille pour moi! Bash 4.3.11
Carlos Nunez
2
Bonne réponse; vous voudrez peut-être souligner que c'est mieux que des solutions telles que eval $(printf "cd ..;%.s" $(seq $1))lesquelles cdplusieurs fois, car ~-aka $OLDPWDest défini dans le répertoire de travail avant l'invocation, plutôt que dans un répertoire intermédiaire. PS - cela se simplifie cd $(printf %.s../ $(seq "$1"))si vous le souhaitez.
Toby Speight
10

Une solution simple et low-tech qui ne nécessite aucune configuration. Ne fonctionne que dans les shells avec l' bashédition de commande -style, cependant.

  • Type cd ..
  • Appuyez Up-arrow Returnautant de fois que nécessaire. Très rapide si vous utilisez deux doigts.
Tom Zych
la source
2
haha, pas une mauvaise réponse, je suppose :)
joshmcode
8

Il s'avère que la bonne réponse est «cd + n», où n est le nombre de niveaux que vous souhaitez augmenter. Dommage que cela ne soit documenté nulle part!

Tossrock
la source
17
au moins cela ne fonctionne PAS en bash.
HongboZhu
5
Ne fonctionne pas sur bash 4.2.25 tel qu'il est livré avec Debian. Par curiosité, quel * nix et / ou shell utilisez-vous?
Alexios
Bash a un appel intégré dirsqui prend [+ n] comme argument et affiche le nième répertoire unique qui a été ajouté via pushd. Si vous alias cdà pushd, vous pouvez l' utiliser. Cependant, notez que ce n'est pas techniquement une réponse à la question du PO, car cela a à voir avec des répertoires uniques , ce qui signifie que l'ordre est gâché au fil du temps, lorsque vous revenez aux mêmes répertoires.
Brian Peterson
Oui, pushdet popdprenez également une option [+ n], c'est pourquoi cela peut fonctionner. De plus, bien que ce soit imparfait et indirect, je suppose que cela peut être utilisé comme réponse à la question. Souvent, vous avez récemment visité les répertoires ci-dessus, ils figureront donc dans les 10 derniers répertoires stockés par la pile de répertoires.
Brian Peterson
n'a pas fonctionné pour moi ...
Vass
4

Vous pouvez écrire une fonction (ce doit être une fonction, car vous voulez changer l'état de votre shell lui-même, à savoir le répertoire de travail; une commande externe n'affecterait que son propre processus).

Voici une fonction qui montera un certain nombre de niveaux passés en argument (par défaut 1) dans la structure du répertoire physique (donc, comme cd -P .., n fois):

up() {
    # default parameter to 1 if non provided
    declare -i d=${@:-1}
    # ensure given parameter is non-negative. Print error and return if it is
    (( $d < 0 )) && (>&2 echo "up: Error: negative value provided") && return 1;
    # remove last d directories from pwd, append "/" in case result is empty
    cd "$(pwd | sed -E 's;(/[^/]*){0,'$d'}$;;')/";
}

Utilisez-le comme ceci:

up 4
mgild
la source
1
Bien que ce code puisse répondre à la question, fournir un contexte supplémentaire concernant pourquoi et / ou comment ce code répond à la question améliore sa valeur à long terme.
Donald Duck
1
D'accord, j'ai ajouté quelques commentaires pour vous aider.
mgild
Pour être nitpicky, n'est pas up 4vraiment équivalent à cd /some/dir/supposer $PWD = "/some/dir/that/is/deeply/nested/"?
snapfractalpop
2

Pas exactement ce que vous demandez mais vous devriez regarder dans pushdet popd. Je les trouve beaucoup plus utiles pour la navigation dans les dossiers que certains cd...alias

Si vous allez et vient à partir de quelques zones fixes, la chose habituelle est d'avoir des alias.

alias proj1='cd /some/dir/containing/proj1'
alias proj2='cd /some/deeper/dir/structure/containing/proj2'
Rich Homolka
la source
1

Au lieu d'utiliser des alias, vous pouvez également utiliser la fonction bash suivante:

function mcd() {
  up=""

  for ((i=1; i<=$1;i++)); do
    up="${up}../"
  done

  cd $up
}

(ou en tant que one-liner: function mcd() { up=""; for ((i=1; i<=$1;i++)); do up="${up}../"; done; cd $up; })

L'ajout de cela à votre ~/.bashrcfichier le rendra disponible dans votre terminal et la construction d'une chaîne ../../../../../../avant l'appel cdpermettra également de cd -revenir au répertoire de départ.

Une implémentation plus utile pourrait également contenir des vérifications d'entrée utilisateur:

function mcd() {
    if [[ $1 -lt 1 ]]; then
        echo "Only positive integer values larger than 1 are allowed!" >&2
        echo -e "\n\tUsage:\n\t======\n\n\t\t# to go up 10 levels in your directory\n\t\tmcd 10\n\n\t\t# to go up just 2 levels\n\t\tmcd 2\n" >&2
        return 1;
    fi  

    up=""

    for ((i=1; i<=$1;i++)); do
        up="${up}../"
    done

    cd $up
}
On s'en fout
la source
0

Connaissez-vous le saut automatique ? C'est un hack tiers, mais peut être utile dans votre scénario.

AnonymousLurker
la source
0

Essayez le paramètre d'environnement rarement utilisé CDPATH. Il se peut alors que vous n'ayez pas à définir explicitement le niveau.

Exemple:

$ find workspace -type d
workspace
workspace/project1
workspace/project1/com
workspace/project1/com/java
workspace/project1/com/java/lang

$ CDPATH=".:~/workspace:~/workspace/project1:~/workspace/project1/com:~/workspace/project1/com/java:~/workspace/project1/com/java/lang"
$ cd com
$ pwd
~/workspace/project1/com

Si vous travaillez sur plusieurs projets, vous pouvez définir le paramètre CDPATH dans un fichier d'environnement spécifique au projet. Et déclenchez-le avec une cale pour une automatisation supplémentaire.

J'ai tendance à utiliser beaucoup pushd et popd. J'ai tendance à utiliser CDPATH pour me laisser passer entre les arborescences de projets plutôt que les sous-répertoires dans un projet - mais en ce moment je travaille sur beaucoup de petits projets, pas quelques gros projets. :)

JezC
la source
0

Si vous êtes précédemment sur le répertoire cible:

luna:/tmp % mkdir -p a/b/c/d
luna:/tmp % pwd
/tmp
luna:/tmp % cd a/b/c/d
luna:d % pwd
/tmp/a/b/c/d
luna:d % cd -
luna:/tmp % pwd
/tmp
luna:/tmp % 
masm
la source
0

Jetez un oeil à DirB . Il s'agit d'un script BASH qui vous permet de créer des signets comme suit:

OPERATIONS

  • s Enregistrer un signet de répertoire
  • g aller dans un signet ou un répertoire nommé
  • p poussez un signet / répertoire sur la pile dir
  • r supprimer le signet enregistré
  • d afficher le chemin du répertoire marqué d'un signet
  • sl imprimer la liste des signets du répertoire

Très simple, très efficace.

rseal
la source
0

Allez plus loin dans la réponse de @ Grigory:

function cd_up() {
if [ -z "$1" ]; then
    cd ..
else
    cd $(printf "%0.s../" $(seq 1 $1 ))
fi
}
alias 'cdd'='cd_up'

C'est :

// go up 1 directory level 
$cdd

// go up 3 directory level 
$cdd 3
qun
la source
0

Je suis tombé malade de ce même problème et j'ai fini par écrire cd-plus . Un utilitaire CLI à fichier unique qui vous permet de monter plusieurs répertoires.

Usage

echo `pwd` # /foo/bar/foobar/baz/foobaz/bazfoo
d baz

echo `pwd` # /foo/bar/
Kevin S Lin
la source
0

L'ajout du code ci-dessous à votre .bashrcextension étendra cdl'achèvement pour honorer la notation à trois points.

_cd_dot_expansion() {
    local path="${COMP_WORDS[COMP_CWORD]}"

    if [[ "${path}" =~ ^\.{3,} ]]; then
        local dots="${BASH_REMATCH}"
        local levels="${#dots}"
        local tail="${path##*...}"
        local expanded_dots='..'

        # the loop starts at two because the first set of dots is
        # assigned to `expanded_dots` when it is initialized
        for (( i = 2; i < "${levels}"; i++ )); do
            expanded_dots+='/..'
        done

        path="${expanded_dots}${tail}"
        COMPREPLY=( $( compgen -A file "${path}" ) )

        return
    fi

    _cd
}

complete -o nospace -F _cd_dot_expansion cd

Une fois que cet extrait est exécuté dans votre shell bash, taper cd .../et frapper <TAB>complètera le chemin d'accès ../../et listera les chemins relatifs de tous les répertoires qui sont à deux niveaux, par exemple.

Mise à jour : bash-completiondoit être installé pour avoir accès à la _cdméthode référencée dans le code ci-dessus. Il est installable via la plupart des gestionnaires de packages de ligne de commande

Grant Humphries
la source