Dosya dizin yolunu dosya yolundan al


400

Bash'de, VAR="/home/me/mydir/file.c"nasıl, nasıl alabilirim "/home/me/mydir"?

Yanıtlar:


648

dirnameve basenameyol bileşenlerini çıkarmak için aradığınız araçlardır:

$ VAR=/home/me/mydir/file.c

$ DIR=$(dirname "${VAR}")

$ echo "${DIR}"
/home/me/mydir

$ basename "${VAR}"
file.c

Bunlar dahili Bash komutları değildir, ancak POSIX standardının (bkz dirname. basename) Bir parçasıdır ve bu nedenle Bash çalıştıracak sistemlerin büyük çoğunluğunda mevcut olmalıdır.


4
Neden "$ VAR" değil de değişken adları etrafında köşeli ayraç kullanımı?
— user658182

1
stackoverflow.com/questions/8748831/… yukarıdaki soruya cevap veriyor.
— user658182

1
@ user658182 Bu özel örnekte, zorunluluk değil alışkanlıktan yapılmıştır.
— Terk Edilmiş Sepet

95
$ export VAR=/home/me/mydir/file.c
$ export DIR=${VAR%/*}
$ echo "${DIR}"
/home/me/mydir

$ echo "${VAR##*/}"
file.c

basenameVe ile bağımlılığı önlemek içindirname


3
Her ikisi de POSIX'in bir parçası olduğundan, bağımlılık sorun olmamalıdır.
— orkoden

1
orkoden, haklısın. Cevabımın amacı, iki ek işlem yürütme zorunluluğu olmadığını göstermektir. bash kullanım durumu için kendi kendine yeterlidir.
— Emmanuel Devaux

2
Emmanuel'in yöntemini kullanıyorum çünkü bir dosya veya klasör adı iletmek ve sonra klasör yolunu hesaplamak istiyorum. Bu regex kullanmak doğru olanı yapar, ancak bir klasör girdiğimde dirname işlevi üst klasörü döndürdü.
— AnneTheAgile

8
Ancak, $ VAR'da yol bilgisi yoksa, $ {VAR% / *} / test $ VAR / test değerine eşit beklenmedik bir değer üretirken, $ (dirname $ VAR) ./test için daha öngörülebilir ve uygun değer üretir. Bu büyük bir mesele çünkü birincisi dosya adını bir dizin olarak ele almaya çalışırken ikincisi TAMAM olacaktır.
— davemyron

19

İlgili bir notta, yalnızca dosya adına veya göreli yola sahipseniz, dirnamekendi başına yardımcı olmaz. Benim için cevap sona erdi readlink.

fname='txtfile'    
echo $(dirname "$fname")                # output: .
echo $(readlink -f "$fname")            # output: /home/me/work/txtfile

Daha sonra ikisini birleştirerek sadece dizini alabilirsiniz.

echo $(dirname $(readlink -f "$fname")) # output: /home/me/work

1
birden fazla yol bileşeni mevcut değilse, readlink -m "$fname"verilen adı özyinelemede kurallı hale getirmek için kullanmalısınız
— EDkan

7

Hedef dosyaların sembolik bağlantı olmasını düşünüyorsanız, önce dosyayı kontrol edebilir ve orijinal dosyayı alabilirsiniz. Aşağıdaki if cümlesi size yardımcı olabilir.

if [ -h $file ]
then
 base=$(dirname $(readlink $file))
else
 base=$(dirname $file)
fi

5

Bununla oynuyordum ve bir alternatif buldum.

$ VAR=/home/me/mydir/file.c

$ DIR=`echo $VAR |xargs dirname`

$ echo $DIR
/home/me/mydir

Sevdiğim bölüm, ağacı yedeklemeyi uzatmanın kolay olmasıydı:

$ DIR=`echo $VAR |xargs dirname |xargs dirname |xargs dirname`

$ echo $DIR
/home

1

İşte özyinelemeli kırpma için kullandığım bir komut dosyası. Elbette $ 1 yerine istediğiniz dizini girin.

BASEDIR="$1"
IFS=$'\n'
cd $BASEDIR
 for f in $(find . -type f -name ' *')
 do 
    DIR=$(dirname "$f")
    DIR=${DIR:1}
    cd $BASEDIR$DIR
    rename 's/^ *//' *
 done

0

İlk olarak, yerine /boşluk bıraktım ( ). Sonra, boşluktan önceki tüm karakterleri sildim ( ). Sonunda, boşluk olan ilk karakteri ( ) kaldırdım .

$ VAR="/home/me/mydir/file.c"

$ echo $VAR | tr '/' ' ' | sed 's/^.* / /' | cut -c2-
file.c

0
HERE=$(cd $(dirname $BASH_SOURCE) && pwd)

burada new_path = ile tam yolu elde edersiniz$(dirname ${BASH_SOURCE[0]}) . Geçerli dizini cd new_path ile değiştirir ve geçerli dizinin pwdtam yolunu almak için çalıştırırsınız .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.