Dateiverzeichnispfad vom Dateipfad abrufen

400

Wenn in Bash, wenn VAR="/home/me/mydir/file.c", wie komme ich "/home/me/mydir"?

Talespin_Kit
quelle

Antworten:

648

dirnameund basenamesind die Tools, nach denen Sie suchen, um Pfadkomponenten zu extrahieren:

$ VAR=/home/me/mydir/file.c

$ DIR=$(dirname "${VAR}")

$ echo "${DIR}"
/home/me/mydir

$ basename "${VAR}"
file.c

Sie sind nicht interne Bash Befehle , aber sie sind Teil des POSIX - Standard (siehe dirname, basename) und sollte so auf die überwiegende Mehrheit der Systeme zur Verfügung , die Bash laufen wird.

paxdiablo
quelle
4
Warum die Verwendung von Klammern um die Variablennamen und nicht "$ VAR" zum Beispiel?
user658182
1
stackoverflow.com/questions/8748831/… beantwortet die obige Frage.
user658182
1
@ user658182 In diesem speziellen Beispiel geschieht dies aus Gewohnheit und nicht aus Notwendigkeit.
Verlassener Wagen
95
$ export VAR=/home/me/mydir/file.c
$ export DIR=${VAR%/*}
$ echo "${DIR}"
/home/me/mydir

$ echo "${VAR##*/}"
file.c

Um die Abhängigkeit von basenameund zu vermeidendirname

Emmanuel Devaux
quelle
3
Da beide Teil von POSIX sind, sollte eine Abhängigkeit kein Problem sein.
Orkoden
1
Orkoden, du hast recht. Mit meiner Antwort möchte ich zeigen, dass keine Verpflichtung besteht, zwei zusätzliche Prozesse auszuführen. bash ist für den Anwendungsfall autark.
Emmanuel Devaux
2
Ich verwende Emmanuels Methode, weil ich entweder eine Datei oder einen Ordnernamen übergeben und dann den Ordnerpfad berechnen möchte. Die Verwendung dieses regulären Ausdrucks ist das Richtige, während die Funktion dirname den übergeordneten Ordner zurückgab, wenn ich einen Ordner eingab.
AnneTheAgile
8
Wenn jedoch in $ VAR keine Pfadinformationen vorhanden sind, erzeugt $ {VAR% / *} / test einen unerwarteten Wert gleich $ VAR / test, während $ (dirname $ VAR) den vorhersehbareren und angemesseneren Wert von ./test erzeugt. Dies ist eine große Sache, da der erstere versucht, den Dateinamen als Verzeichnis zu behandeln, während der letztere in Ordnung ist.
Davemyron
19

Wenn Sie nur den Dateinamen oder den relativen Pfad haben, dirnamehilft dies nicht. Für mich war die Antwort letztendlich readlink.

fname='txtfile'    
echo $(dirname "$fname")                # output: .
echo $(readlink -f "$fname")            # output: /home/me/work/txtfile

Sie können dann beide kombinieren, um nur das Verzeichnis zu erhalten.

echo $(dirname $(readlink -f "$fname")) # output: /home/me/work
jerblack
quelle
1
Wenn nicht mehr als eine Pfadkomponente vorhanden war, sollten Sie den readlink -m "$fname"angegebenen Namen rekursiv
kanonisieren
7

Wenn Sie möchten, dass Zieldateien ein symbolischer Link sind, können Sie dies zunächst überprüfen und die Originaldatei abrufen. Die folgende if-Klausel kann Ihnen helfen.

if [ -h $file ]
then
 base=$(dirname $(readlink $file))
else
 base=$(dirname $file)
fi
Tahsin Turkoz
quelle
5

Ich habe damit gespielt und mir eine Alternative ausgedacht.

$ VAR=/home/me/mydir/file.c

$ DIR=`echo $VAR |xargs dirname`

$ echo $DIR
/home/me/mydir

Der Teil, den ich mochte, war, dass es einfach war, die Sicherung des Baums zu erweitern:

$ DIR=`echo $VAR |xargs dirname |xargs dirname |xargs dirname`

$ echo $DIR
/home
Eurospoofer
quelle
1

Hier ist ein Skript, das ich zum rekursiven Trimmen verwendet habe. Ersetzen Sie $ 1 natürlich durch das gewünschte Verzeichnis.

BASEDIR="$1"
IFS=$'\n'
cd $BASEDIR
 for f in $(find . -type f -name ' *')
 do 
    DIR=$(dirname "$f")
    DIR=${DIR:1}
    cd $BASEDIR$DIR
    rename 's/^ *//' *
 done
kmchen
quelle
0

Zuerst habe ich durch /Leerzeichen ( ) ersetzt. Dann habe ich alle Zeichen vor einem leeren Leerzeichen gelöscht ( ). Am Ende habe ich das erste Zeichen entfernt, das Leerzeichen ist ( ).

$ VAR="/home/me/mydir/file.c"

$ echo $VAR | tr '/' ' ' | sed 's/^.* / /' | cut -c2-
file.c
alper
quelle
0
HERE=$(cd $(dirname $BASH_SOURCE) && pwd)

wo Sie den vollständigen Pfad mit new_path = erhalten $(dirname ${BASH_SOURCE[0]}). Sie ändern das aktuelle Verzeichnis mit cd new_path und führen es aus pwd, um den vollständigen Pfad zum aktuellen Verzeichnis abzurufen .

Aerijman
quelle