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?

Aubergine
quelle

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"
David W.
quelle
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.
26

Das Gegenteil von dirnameist basename:

basename "$(dirname "/from/here/to/there.txt")"
dieser andere Typ
quelle
23

Verwenden von bashZeichenfolgenfunktionen:

$ s="/from/here/to/there.txt"
$ s="${s%/*}" && echo "${s##*/}"
to
jaypal singh
quelle
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.

Codeforester
quelle
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
Anubhava
quelle
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 )
csiu
quelle
2

Noch ein Weg

IFS=/ read -ra x <<<"/from/here/to/there.txt" && printf "%s\n" "${x[-2]}"
iruvar
quelle
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
MLSC
quelle
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
Yashma
quelle