So erhalten Sie den letzten Teil von dirname in Bash


80

Angenommen , ich habe eine Datei /from/here/to/there.txt, und will nur den letzten Teil seiner dirname bekommen tostatt /from/here/to, was soll ich tun?

Antworten:


117

Sie können verwenden basename, obwohl es keine Datei ist. Entfernen Sie den Dateinamen mit dirnameund verwenden Sie dann basename, um das letzte Element der Zeichenfolge abzurufen:

dir="/from/here/to/there.txt"
dir="$(dirname $dir)"   # Returns "/from/here/to"
dir="$(basename $dir)"  # Returns just "to"

2
Der Befehl '$ dir = "$ (dirname $ dir)"' funktioniert bei mir nicht, aber 'dir = "$ (dirname $ dir)"' funktioniert einwandfrei.
Nikolai Saiko

2
Ich hätte den Dollar nicht vor mir haben sollen, dirwenn ich ihn einstelle.
David W.


23

Verwenden von bashZeichenfolgenfunktionen:

$ s="/from/here/to/there.txt"
$ s="${s%/*}" && echo "${s##*/}"
to

9

Mit der Bash- Parametererweiterung können Sie Folgendes tun:

path="/from/here/to/there.txt"
dir="${path%/*}"       # sets dir      to '/from/here/to' (equivalent of dirname)
last_dir="${dir##*/}"  # sets last_dir to 'to' (equivalent of basename)

Dies ist effizienter, da keine externen Befehle verwendet werden.


Ich habe das gerade getestet. Auf FreeBSD sind hier meine Ergebnisse: Code: #! / Bin / sh cd / var / svn / repos path = "$ 1" echo "$ {path}" dir = "$ {path% / *}" echo "$ {dir } "actual =" $ {dir ## * /} "echo" $ {actual} "----------------------------- ----------- Ergebnisse: $ ./makerepo.sh / var / test / var / test / var var $ ------------------- ----------------- Scheitern! Es tut uns leid. Schien eine gute Methode, aber keine richtige Antwort.
Richard Robertson

4

Pure BASH Weg:

s="/from/here/to/there.txt"
[[ "$s" =~ ([^/]+)/[^/]+$ ]] && echo "${BASH_REMATCH[1]}"
to

2
Funktioniert nicht, wenn die Datei keinen Punkt hat .. Funktioniert nicht, wenn das Verzeichnis einen Punkt hat .. Halten Sie es einfach und verwenden Sie einen Schrägstrich /als Trennzeichen.
Alvits

1
Vielen Dank @Akshay
Anubhava

3

Ein awkWeg, dies zu tun, wäre:

awk -F'/' '{print $(NF-1)}' <<< "/from/here/to/there.txt"

Erläuterung:

  • -F'/' setzt das Feldtrennzeichen auf "/"
  • Drucken Sie das vorletzte Feld $(NF-1)
  • <<<verwendet alles danach als Standardeingabe ( Wiki-Erklärung )

2

Noch ein Weg

IFS=/ read -ra x <<<"/from/here/to/there.txt" && printf "%s\n" "${x[-2]}"

Einfacher zu bedienen : printf "%s\n" "${x[-2]}".
gniourf_gniourf

1

Diese Frage ist so etwas wie DIESES .

Um dies zu lösen, können Sie Folgendes tun:

DirPath="/from/here/to/there.txt"
DirPath="$(dirname $DirPath)"
DirPath="$(basename $DirPath)"

echo "$DirPath"

Wie mein Freund sagte, ist dies auch möglich:

basename `dirname "/from/here/to/there.txt"`

Um einen Teil Ihres Weges zu erreichen, können Sie Folgendes tun:

echo "/from/here/to/there.txt" | awk -F/ '{ print $2 }'
OR
echo "/from/here/to/there.txt" | awk -F/ '{ print $3 }'
OR
etc

1

Die Top-Antwort ist für die gestellte Frage absolut richtig. In einem allgemeineren Fall mit dem benötigten Verzeichnis in der Mitte eines langen Pfades führt dieser Ansatz zu einem schwer lesbaren Code. Zum Beispiel :

dir="/very/long/path/where/THIS/needs/to/be/extracted/text.txt"
dir="$(dirname $dir)"
dir="$(dirname $dir)"
dir="$(dirname $dir)"
dir="$(dirname $dir)"
dir="$(dirname $dir)"
dir="$(basename $dir)"

In diesem Fall kann man verwenden:

IFS=/; set -- "/very/long/path/where/THIS/needs/to/be/extracted/text.txt"; set $1; echo $6
THIS
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.