Bash CD bis in einen bestimmten Ordner


16

Ich arbeite viel in Magento und auch viele Leute, mit denen ich arbeite, und es wird ärgerlich, Folgendes eingeben zu müssen:

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

Um nur zu finden, dass Sie noch ein paar Verzeichnisse in Ihrem Stammordner "httpdocs" haben, versuche ich, ein Skript zu erstellen, das diesem Pseudocode folgt:

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

Scheint ziemlich einfach zu sein, ich nehme an, ich müsste in irgendeiner Form prüfen, ob der letzte Teil des aktuellen Arbeitsverzeichnisses httpdocs ist, wenn nicht einfach so lange, bis es wahr ist.

Ich habe versucht, Bash dafür zu lernen, obwohl es den Anschein hat, dass es da draußen schon etwas gibt, das ähnlich ist, und die Syntax verwirrt mich bis zum Äußersten.

Antworten:


8

Dies muss eine Shell-Funktion sein , kein Skript, da ein Skript in einer neuen Shell ausgeführt wird (und daher das Verzeichnis der ursprünglichen Shell nicht ändern kann).

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

Sie können die Funktion natürlich beliebig benennen.

Einige Erklärungen: Der erste Test ( $PWD != '/') ist cdrootausfallsicher, wenn Sie sich nicht in einem httpdocs-Ordner befinden. Es wird aufhören, wenn Sie an die Wurzel gelangen.

Der zweite Test ( ${PWD##*/} != 'httpdocs') ist etwas komplizierter. $PWDist eine Variable, die den Pfad des aktuellen Verzeichnisses enthält. ${PWD##*/}schneidet alles bis einschließlich des letzten Schrägstrichs.


Der Nachteil dieses iterativen Schritts ist, dass Sie Ihre Fähigkeit verlieren, nur noch einen cd -Schritt später zu tun, um dorthin zurückzukehren, wo Sie waren.
Ezequiel Muns

27

Ich habe eine Funktion, die uptoin meinem .bashrc aufgerufen wird und es Ihnen ermöglicht, mit Namen in ein beliebiges Verzeichnis auf dem aktuellen Pfad zu gelangen:

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

Ich habe auch Abschluss für diese Funktion, so dass es mir gültige Verzeichnisnamen und Abschluss gibt, wenn ich die Tabulatortaste drücke:

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

Zusätzlich habe ich eine weitere Funktion jd, mit der ich in ein beliebiges Verzeichnis unterhalb des aktuellen Verzeichnisses springen kann:

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

Beispiel:

[/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] $ 

Sie können auch einen Alias ​​für hinzufügen upto httpdocs.
cjm

@drogbane: jdscheint nicht in jedem Fall zu funktionieren. Würde es Ihnen etwas ausmachen zu erklären, wie es funktioniert?
Cesar

@Cesar verwendet globstar ( **). Um diese Funktion in Ihrer Bash-Shell zu aktivieren, verwenden Sie shopt -s globstar.
Dogbane

2
Das ist so brillant gemacht, ich wünschte, ich könnte zweimal upvoten.
Droope

1
Ich habe eine dynamische Shopt-Erkennung und -Aktivierung in die jdFunktion aufgenommen, siehe gist.github.com/Rob--W/5888648 . Ich habe es nur mit Bash 4.2.45 getestet, also YMMV.
Rob W

5

Die einfachste Bash-Funktion, die Sie in Ihre einfügen können, .bashrcdie mir einfällt (einfach, weil sie keine Schleifen oder externen Prozesse verwendet), ist:

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

Dies verwendet die Pattern Substitution Parameter Expansion alles zu ersetzen , nachdem /httpdocs/in $PWDmit `/ httpdocs'. Es sieht sehr chaotisch aus, da wir die Schrägstriche im Pfad umgehen müssen, um sie von den Schrägstrichen in der Bash-Erweiterungssyntax zu unterscheiden. Vermeiden Sie außerdem Schrägstriche in der Ersetzungszeichenfolge, sodass diese ebenfalls inkonsistent aussieht.

Wenn /httpdocs/der aktuelle Pfad keine enthält, werden keine Ersetzungen durchgeführt, und es wird nur in das aktuelle Verzeichnis gewechselt.

Zum Beispiel ersetzt die Substitution /a/b/c/httpdocs/e/f/gmit /a/b/c/httpdocsund cdin dieses Verzeichnis.

Die Funktion muss sich in Ihrer aktuellen Shell-Umgebung befinden (entweder als Funktion oder als Alias), da ein untergeordneter Prozess das aktuelle Verzeichnis seines übergeordneten Prozesses nicht ändern kann. Aus diesem Grund sage ich, dass Sie es in Ihr .bashrcund nicht in ein Shell-Skript einfügen sollen.


Übrigens ist es erwähnenswert, dass Sie dadurch in der Hierarchie so weit oben wie möglich stehen (was wahrscheinlich der nützlichste Anwendungsfall ist).
Ibrahim

3

Sie könnten auch so etwas in Ihr Profil aufnehmen:

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

Durch einfaches Eingeben cdhgelangen Sie zum obersten httpdocsVerzeichnis in Ihrem aktuellen Pfad.


2

Es wird Ihr Problem nicht vollständig lösen, aber es wird cd ../../../../../../ein wenig Zeit sparen . Ich habe dies von dem Beitrag des Benutzers unknown hier ausgeliehen .


bis N

N Verzeichnisse im Verzeichnisbaum nach oben springen

Anstatt zu tippen

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

du tippst einfach

up 4

und ein

cd -    

bringt dich zurück

Fügen Sie die Funktion in Ihr .bashrc ein, um sie zu verwenden.

# (c) 2007 stefan w. GPLv3          
function up {
ups=""
for i in $(seq 1 $1)
do
        ups=$ups"../"
done
cd $ups
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.