Böyle bir dosya yolum varsa ...
/home/smith/Desktop/Test
/home/smith/Desktop/Test/
Dizeyi üst dizin olacak şekilde nasıl değiştirebilirim?
Örneğin
/home/smith/Desktop
/home/smith/Desktop/
Böyle bir dosya yolum varsa ...
/home/smith/Desktop/Test
/home/smith/Desktop/Test/
Dizeyi üst dizin olacak şekilde nasıl değiştirebilirim?
Örneğin
/home/smith/Desktop
/home/smith/Desktop/
Yanıtlar:
dir=/home/smith/Desktop/Test
parentdir="$(dirname "$dir")"
Sonunda eğik çizgi varsa da çalışır.
parentdir=$(dirname `pwd`)
... ama burada görülen şey bozuldu. İşte düzeltme:
> pwd
/home/me
> x='Om Namah Shivaya'
> mkdir "$x" && cd "$x"
/home/me/Om Namah Shivaya
> parentdir="$(dirname "$(pwd)")"
> echo $parentdir
/home/me
echo $(cd ../ && pwd)
Üst dizinini bulmak istediğiniz dizinde çalışırken kullanın . Bu zincir aynı zamanda sondaki eğik çizgilere sahip olmama avantajına sahiptir.
echo
Burada ihtiyacın yok.
Üst dizin açıkça nokta-nokta dosya adı eklenerek verilir:
/home/smith/Desktop/Test/.. # unresolved path
Ancak çözümlenmiş yolu (herhangi bir nokta-nokta yolu bileşeni olmayan mutlak bir yol) istemeniz gerekir :
/home/smith/Desktop # resolved path
Kullanan en iyi yanıtlardaki sorun, dirname
nokta noktalı bir yol girdiğinizde çalışmaz olmalarıdır:
$ dir=~/Library/../Desktop/../..
$ parentdir="$(dirname "$dir")"
$ echo $parentdir
/Users/username/Library/../Desktop/.. # not fully resolved
Bu daha güçlü :
dir=/home/smith/Desktop/Test
parentdir=`eval "cd $dir;pwd;cd - > /dev/null"`
Besleyebilirsiniz /home/smith/Desktop/Test/..
, ancak daha karmaşık yollar da olabilir:
$ dir=~/Library/../Desktop/../..
$ parentdir=`eval "cd $dir;pwd;cd - > /dev/null"`
$ echo $parentdir
/Users # the fully resolved path!
EDIT: Eğer işe yaramazsa cd
, bazen yaygın uygulama gibi,
$ which cd
cd is a function #cd was modified to print extra info, so use "builtin cd" to override
cd ()
{
builtin cd "$@";
ls -FGAhp
}
...
eval
Sizi beklemediğiniz bir yere koyabilecek veya sisteminize karşı kötü şeyler çalıştırabilecek kullanıcı girişlerini ayrıştırma şansı varsa kullanmak harika DEĞİLDİR. pushd $dir 2>&1 >/dev/null && pwd && popd 2>&1 >/dev/null
Bunun yerine kullanabilir misiniz eval
?
eval
yok: sadece yapın parentdir=$(cd -- "$dir" && pwd)
. Yana cd
bir kabuktaki çalıştırılır, sen gerekmez cd
kaldığımız yerden devam arkasına. --
Diye burada genişlemesi olan $dir
bir tire ile başlar. Bu &&
, işe yaramadığında parentdir
boş olmayan bir içeriğe sahip cd
olmaktan kaçınmaktır.
Çok kısa, net, garantili kodu seviyorum. Harici bir program çalıştırmazsa bonus noktası, çok sayıda girişi işlemden geçirmeniz gereken günden beri belirgin şekilde daha hızlı olacaktır.
Ne garanti ve istediğinizi emin değilim, bu yüzden zaten teklif.
Garantileriniz varsa bunu çok kısa kod ile yapabilirsiniz. Buradaki fikir, son eğik çizgiyi ve ardından gelenleri kesmek için bash metin değiştirme özelliğini kullanmaktır.
Orijinal sorunun basit ve daha karmaşık vakalarına cevap verin.
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]}
bunun üzerinden kaynaklı değildi eğer komut için tam yolu olurdu source
veya .
.
İstediğiniz /home/smith/Desktop/Test/../
şey ise:
dirname 'path/to/child/dir'
burada görüldüğü gibi .
bash: dirname 'Test': syntax error: invalid arithmetic operator (error token is "'Test'")
. Bağlantılı kod da yanlış.
dirname Test
dizinden Test
içindedir.
Mutlak yollara ihtiyacınız olup olmadığına bağlı olarak, fazladan bir adım atmak isteyebilirsiniz:
child='/home/smith/Desktop/Test/'
parent=$(dirname "$child")
abs_parent=$(realpath "$parent")
bunu kullanın: export MYVAR="$(dirname "$(dirname "$(dirname "$(dirname $PWD)")")")"
4. üst dizin istiyorsanız
export MYVAR="$(dirname "$(dirname "$(dirname $PWD)")")"
3. üst dizin istiyorsanız
export MYVAR="$(dirname "$(dirname $PWD)")"
2. üst dizin istiyorsanız
çirkin ama verimli
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_: /
Başlayan fikir / yorum Charles Duffy - Dec 17 '14 zaman 5:32 konusunda Konuyla ilgili Bash script geçerli dizin adı (tam yol olmadan) alın
#!/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;
Sebebi ne olursa olsun sen dizinleri belirli sayıda yukarı gezinme ilgilenen varsa da yapabilirdi: nth_path=$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && cd ../../../ && pwd)
. Bu, 3 ebeveyn dizinini bırakacaktır
..
' kullanabilirsiniz , ancak belki de aklınızdaki şey bu olmayabilir.