Wenn ich einen Dateipfad habe wie ...
/home/smith/Desktop/Test
/home/smith/Desktop/Test/
Wie ändere ich die Zeichenfolge so, dass sie das übergeordnete Verzeichnis ist?
z.B
/home/smith/Desktop
/home/smith/Desktop/
Wenn ich einen Dateipfad habe wie ...
/home/smith/Desktop/Test
/home/smith/Desktop/Test/
Wie ändere ich die Zeichenfolge so, dass sie das übergeordnete Verzeichnis ist?
z.B
/home/smith/Desktop
/home/smith/Desktop/
Antworten:
dir=/home/smith/Desktop/Test
parentdir="$(dirname "$dir")"
Funktioniert auch, wenn es einen abschließenden Schrägstrich gibt.
parentdir=$(dirname `pwd`)
... aber was " hier gesehen " ist kaputt. Hier ist das Update:
> pwd
/home/me
> x='Om Namah Shivaya'
> mkdir "$x" && cd "$x"
/home/me/Om Namah Shivaya
> parentdir="$(dirname "$(pwd)")"
> echo $parentdir
/home/me
Verwenden Sie einfach, echo $(cd ../ && pwd)während Sie in dem Verzeichnis arbeiten, dessen übergeordnetes Verzeichnis Sie herausfinden möchten. Diese Kette hat auch den zusätzlichen Vorteil, dass sie keine nachlaufenden Schrägstriche aufweist.
echohier nicht.
Das übergeordnete Verzeichnis wird eindeutig durch einfaches Anhängen des Punkt-Punkt-Dateinamens angegeben:
/home/smith/Desktop/Test/.. # unresolved path
Sie müssen jedoch den aufgelösten Pfad (einen absoluten Pfad ohne Punkt-Punkt-Pfad-Komponenten) möchten :
/home/smith/Desktop # resolved path
Das Problem mit den häufigsten Antworten dirnameist, dass sie nicht funktionieren, wenn Sie einen Pfad mit Punktpunkten eingeben:
$ dir=~/Library/../Desktop/../..
$ parentdir="$(dirname "$dir")"
$ echo $parentdir
/Users/username/Library/../Desktop/.. # not fully resolved
Das ist mächtiger :
dir=/home/smith/Desktop/Test
parentdir=`eval "cd $dir;pwd;cd - > /dev/null"`
Sie können es füttern /home/smith/Desktop/Test/.., aber auch komplexere Pfade wie:
$ dir=~/Library/../Desktop/../..
$ parentdir=`eval "cd $dir;pwd;cd - > /dev/null"`
$ echo $parentdir
/Users # the fully resolved path!
BEARBEITEN: Wenn es nicht funktioniert, überprüfen Sie, ob Sie cdnicht geändert wurden, wie es manchmal üblich ist.
$ which cd
cd is a function #cd was modified to print extra info, so use "builtin cd" to override
cd ()
{
builtin cd "$@";
ls -FGAhp
}
...
evalist NICHT großartig, wenn die Möglichkeit besteht, Benutzereingaben zu analysieren, die Sie an einen Ort bringen könnten, an dem Sie keine schlechten Dinge erwarten oder gegen Ihr System ausführen. Können Sie pushd $dir 2>&1 >/dev/null && pwd && popd 2>&1 >/dev/nullanstelle der verwenden eval?
evalüberhaupt nicht: tun Sie es einfach parentdir=$(cd -- "$dir" && pwd). Da das cdin einer Subshell ausgeführt wird, müssen Sie nicht dorthin zurückkehren, cdwo wir waren. Das --ist hier für den Fall, dass die Erweiterung von $dirmit einem Bindestrich beginnt. Das &&soll nur verhindern parentdir, dass ein nicht leerer Inhalt vorhanden ist, wenn der cdnicht erfolgreich war.
Ich mag sehr kurzen, klaren, garantierten Code. Bonuspunkt, wenn kein externes Programm ausgeführt wird, da es an dem Tag, an dem Sie eine große Anzahl von Einträgen verarbeiten müssen, spürbar schneller ist.
Ich bin mir nicht sicher, welche Garantien Sie haben und wollen, also bieten Sie es trotzdem an.
Wenn Sie Garantien haben, können Sie dies mit sehr kurzem Code tun. Die Idee ist, die Bash-Textersetzungsfunktion zu verwenden, um den letzten Schrägstrich und was auch immer folgt, zu schneiden.
Beantworten Sie einfache bis komplexere Fälle der ursprünglichen Frage.
P=/home/smith/Desktop/Test ; echo "${P%/*}"
/home/smith/Desktop
P=/home/smith/Desktop/Test/ ; echo "${P%/*/}/"
/home/smith/Desktop/
for P in \
/home/smith/Desktop/Test \
/home/smith/Desktop/Test/
do
P_ENDNOSLASH="${P%/}" ; echo "${P_ENDNOSLASH%/*}"
done
/home/smith/Desktop
/home/smith/Desktop
for P in \
/home/smith/Desktop/Test \
/home/smith/Desktop/Test/ \
/home/smith///Desktop////Test//
do
P_NODUPSLASH="${P//\/*(\/)/\/}"
P_ENDNOSLASH="${P_NODUPSLASH%%/}"
echo "${P_ENDNOSLASH%/*}";
done
/home/smith/Desktop
/home/smith/Desktop
/home/smith/Desktop
${BASH_SOURCE[0]}wäre der vollständige Pfad zum Skript, wenn es nicht über sourceoder bezogen würde ..
Wenn /home/smith/Desktop/Test/../es das ist, was Sie wollen:
dirname 'path/to/child/dir'
wie hier gesehen .
bash: dirname 'Test': syntax error: invalid arithmetic operator (error token is "'Test'"). Verknüpfter Code ist auch falsch.
dirname Testaus dem Verzeichnis zu laufen Testist in.
Je nachdem, ob Sie absolute Pfade benötigen, möchten Sie möglicherweise einen zusätzlichen Schritt ausführen:
child='/home/smith/Desktop/Test/'
parent=$(dirname "$child")
abs_parent=$(realpath "$parent")
Verwenden Sie dies: export MYVAR="$(dirname "$(dirname "$(dirname "$(dirname $PWD)")")")"Wenn Sie das 4. übergeordnete Verzeichnis möchten
export MYVAR="$(dirname "$(dirname "$(dirname $PWD)")")"
Wenn Sie das 3. übergeordnete Verzeichnis möchten
export MYVAR="$(dirname "$(dirname $PWD)")"
Wenn Sie das 2. übergeordnete Verzeichnis möchten
hässlich aber effizient
function Parentdir()
{
local lookFor_ parent_ switch_ i_
lookFor_="$1"
#if it is not a file, we need the grand parent
[ -f "$lookFor_" ] || switch_="/.."
#length of search string
i_="${#lookFor_}"
#remove string one by one until it make sens for the system
while [ "$i_" -ge 0 ] && [ ! -d "${lookFor_:0:$i_}" ];
do
let i_--
done
#get real path
parent_="$(realpath "${lookFor_:0:$i_}$switch_")"
#done
echo "
lookFor_: $1
{lookFor_:0:$i_}: ${lookFor_:0:$i_}
realpath {lookFor_:0:$i_}: $(realpath ${lookFor_:0:$i_})
parent_: $parent_
"
}}
lookFor_: /home/Om Namah Shivaya
{lookFor_:0:6}: /home/
realpath {lookFor_:0:6}: /home
parent_: /home
lookFor_: /var/log
{lookFor_:0:8}: /var/log
realpath {lookFor_:0:8}: /UNIONFS/var/log
parent_: /UNIONFS/var
lookFor_: /var/log/
{lookFor_:0:9}: /var/log/
realpath {lookFor_:0:9}: /UNIONFS/var/log
parent_: /UNIONFS/var
lookFor_: /tmp//res.log/..
{lookFor_:0:6}: /tmp//
realpath {lookFor_:0:6}: /tmp
parent_: /
lookFor_: /media/sdc8/../sdc8/Debian_Master//a
{lookFor_:0:35}: /media/sdc8/../sdc8/Debian_Master//
realpath {lookFor_:0:35}: /media/sdc8/Debian_Master
parent_: /media/sdc8
lookFor_: /media/sdc8//Debian_Master/../Debian_Master/a
{lookFor_:0:44}: /media/sdc8//Debian_Master/../Debian_Master/
realpath {lookFor_:0:44}: /media/sdc8/Debian_Master
parent_: /media/sdc8
lookFor_: /media/sdc8/Debian_Master/../Debian_Master/For_Debian
{lookFor_:0:53}: /media/sdc8/Debian_Master/../Debian_Master/For_Debian
realpath {lookFor_:0:53}: /media/sdc8/Debian_Master/For_Debian
parent_: /media/sdc8/Debian_Master
lookFor_: /tmp/../res.log
{lookFor_:0:8}: /tmp/../
realpath {lookFor_:0:8}: /
parent_: /
Ausgehend von der Idee / dem Kommentar Charles Duffy - 17. Dezember 14 um 5:32 Uhr zum Thema Aktuellen Verzeichnisnamen (ohne vollständigen Pfad) in einem Bash-Skript abrufen
#!/bin/bash
#INFO : /programming/1371261/get-current-directory-name-without-full-path-in-a-bash-script
# comment : by Charles Duffy - Dec 17 '14 at 5:32
# at the beginning :
declare -a dirName[]
function getDirNames(){
dirNr="$( IFS=/ read -r -a dirs <<<"${dirTree}"; printf '%s\n' "$((${#dirs[@]} - 1))" )"
for(( cnt=0 ; cnt < ${dirNr} ; cnt++))
do
dirName[$cnt]="$( IFS=/ read -r -a dirs <<<"$PWD"; printf '%s\n' "${dirs[${#dirs[@]} - $(( $cnt+1))]}" )"
#information – feedback
echo "$cnt : ${dirName[$cnt]}"
done
}
dirTree=$PWD;
getDirNames;
Wenn Sie aus irgendeinem Grund daran interessiert sind, durch eine bestimmte Anzahl von Verzeichnissen zu navigieren, können Sie auch Folgendes tun : nth_path=$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && cd ../../../ && pwd). Dies würde 3 Elternverzeichnisse aufgeben
..' verwenden, aber vielleicht ist das nicht ganz das, was Sie sich vorgestellt haben.