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.