Jika saya memiliki jalur file seperti ...
/home/smith/Desktop/Test
/home/smith/Desktop/Test/
Bagaimana cara mengubah string sehingga akan menjadi direktori induk?
misalnya
/home/smith/Desktop
/home/smith/Desktop/
Jika saya memiliki jalur file seperti ...
/home/smith/Desktop/Test
/home/smith/Desktop/Test/
Bagaimana cara mengubah string sehingga akan menjadi direktori induk?
misalnya
/home/smith/Desktop
/home/smith/Desktop/
Jawaban:
dir=/home/smith/Desktop/Test
parentdir="$(dirname "$dir")"
Bekerja jika ada garis miring, juga.
parentdir=$(dirname `pwd`)
... tapi apa yang "terlihat di sini " rusak. Inilah solusinya:
> pwd
/home/me
> x='Om Namah Shivaya'
> mkdir "$x" && cd "$x"
/home/me/Om Namah Shivaya
> parentdir="$(dirname "$(pwd)")"
> echo $parentdir
/home/me
Cukup gunakan echo $(cd ../ && pwd)saat bekerja di direktori yang direktori induknya ingin Anda ketahui. Rantai ini juga memiliki manfaat tambahan karena tidak memiliki garis miring.
echosini.
Jelas direktori induk diberikan hanya dengan menambahkan nama file dot-dot:
/home/smith/Desktop/Test/.. # unresolved path
Tetapi Anda harus menginginkan jalur yang diselesaikan (jalur absolut tanpa komponen jalur titik-titik):
/home/smith/Desktop # resolved path
Masalah dengan jawaban teratas yang digunakan dirname, adalah bahwa mereka tidak berfungsi ketika Anda memasukkan jalur dengan titik-titik:
$ dir=~/Library/../Desktop/../..
$ parentdir="$(dirname "$dir")"
$ echo $parentdir
/Users/username/Library/../Desktop/.. # not fully resolved
Ini lebih kuat :
dir=/home/smith/Desktop/Test
parentdir=`eval "cd $dir;pwd;cd - > /dev/null"`
Anda bisa memberinya makan /home/smith/Desktop/Test/.. , tetapi juga jalur yang lebih kompleks seperti:
$ dir=~/Library/../Desktop/../..
$ parentdir=`eval "cd $dir;pwd;cd - > /dev/null"`
$ echo $parentdir
/Users # the fully resolved path!
EDIT: Jika tidak berhasil, periksa apakah Anda cdbelum dimodifikasi, seperti yang biasa dilakukan,
$ which cd
cd is a function #cd was modified to print extra info, so use "builtin cd" to override
cd ()
{
builtin cd "$@";
ls -FGAhp
}
...
evalTIDAK bagus jika ada kemungkinan parsing input pengguna yang dapat menempatkan Anda di tempat yang tidak Anda harapkan atau menjalankan hal-hal buruk terhadap sistem Anda. Bisakah Anda menggunakan pushd $dir 2>&1 >/dev/null && pwd && popd 2>&1 >/dev/nullbukan eval?
evalsama sekali: lakukan saja parentdir=$(cd -- "$dir" && pwd). Karena cddijalankan dalam subkulit, Anda tidak perlu cdkembali ke tempat kami sebelumnya. Di --sini jika ekspansi $dirdimulai dengan tanda hubung. Ini &&hanya untuk mencegah parentdiragar konten tidak kosong ketika cdtidak berhasil.
Saya suka kode yang sangat singkat, jelas, dan terjamin. Poin bonus jika tidak menjalankan program eksternal, karena pada hari Anda perlu memproses sejumlah besar entri, itu akan terasa lebih cepat.
Tidak yakin dengan jaminan apa yang Anda miliki dan inginkan, jadi tetaplah menawarkan.
Jika Anda memiliki jaminan, Anda dapat melakukannya dengan kode yang sangat singkat. Idenya adalah untuk menggunakan fitur substitusi teks bash untuk memotong garis miring terakhir dan apa pun yang mengikuti.
Jawab dari kasus sederhana hingga yang lebih kompleks dari pertanyaan awal.
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]}yang akan menjadi path lengkap ke skrip jika tidak bersumber melalui sourceatau ..
Jika /home/smith/Desktop/Test/../itu yang Anda inginkan:
dirname 'path/to/child/dir'
seperti yang terlihat di sini .
bash: dirname 'Test': syntax error: invalid arithmetic operator (error token is "'Test'"). Kode tertaut juga salah.
dirname Testdari direktori Test.
Bergantung pada apakah Anda membutuhkan jalur absolut, Anda mungkin ingin mengambil langkah ekstra:
child='/home/smith/Desktop/Test/'
parent=$(dirname "$child")
abs_parent=$(realpath "$parent")
gunakan ini: export MYVAR="$(dirname "$(dirname "$(dirname "$(dirname $PWD)")")")"jika Anda ingin direktori induk ke-4
export MYVAR="$(dirname "$(dirname "$(dirname $PWD)")")"
jika Anda ingin direktori induk ke-3
export MYVAR="$(dirname "$(dirname $PWD)")"
jika Anda ingin direktori induk ke-2
jelek tapi efisien
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_: /
Dimulai dari ide / komentar Charles Duffy - 17 Des '14 jam 5:32 pada topik Dapatkan nama direktori saat ini (tanpa path lengkap) dalam skrip Bash
#!/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;
jika karena alasan apapun Anda tertarik dalam menjelajahi sampai jumlah tertentu direktori Anda juga bisa melakukan: nth_path=$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && cd ../../../ && pwd). Ini akan memberikan 3 direktori orang tua
..', tapi mungkin itu tidak sesuai yang Anda pikirkan.