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.
echo
sini.
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 cd
belum 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
}
...
eval
TIDAK 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/null
bukan eval
?
eval
sama sekali: lakukan saja parentdir=$(cd -- "$dir" && pwd)
. Karena cd
dijalankan dalam subkulit, Anda tidak perlu cd
kembali ke tempat kami sebelumnya. Di --
sini jika ekspansi $dir
dimulai dengan tanda hubung. Ini &&
hanya untuk mencegah parentdir
agar konten tidak kosong ketika cd
tidak 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 source
atau .
.
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 Test
dari 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.