फ़ाइल निर्देशिका पथ फ़ाइल पथ से प्राप्त करें


400

बैश में, अगर VAR="/home/me/mydir/file.c", मुझे कैसे मिलेगा "/home/me/mydir"?

जवाबों:


647

dirnameऔर basenameवे उपकरण हैं जिन्हें आप पथ घटकों को निकालने के लिए देख रहे हैं:

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

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

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

$ basename "${VAR}"
file.c

वे आंतरिक बैश कमांड नहीं हैं, लेकिन वे POSIX मानक का हिस्सा हैं (देखें dirname, basename) और इसलिए सिस्टम के विशाल बहुमत पर उपलब्ध होना चाहिए जो बैश चल रहा होगा।


4
चर नामों के आसपास कोष्ठक का उपयोग क्यों, और उदाहरण के लिए "$ VAR" नहीं?
user658182

1
stackoverflow.com/questions/8748831/… उपरोक्त प्रश्न का उत्तर देता है।
user658182

1
@ user658182 इस विशेष उदाहरण में, यह आदत से बाहर किया जाता है, आवश्यकता नहीं।
कार्ट

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

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

के साथ निर्भरता से बचने के लिए basenameऔरdirname


3
चूँकि दोनों POSIX का हिस्सा हैं, एक निर्भरता एक समस्या नहीं होनी चाहिए।
orkoden

1
orkoden, आप सही कह रहे हैं। मेरे उत्तर का उद्देश्य यह दिखाना है कि दो अतिरिक्त प्रक्रिया को निष्पादित करने की कोई बाध्यता नहीं है। उपयोग मामले के लिए बैश आत्मनिर्भर है।
इमैनुएल देवक्स

2
मैं इमेनुएल की विधि का उपयोग कर रहा हूं क्योंकि मैं या तो एक फाइल या एक फ़ोल्डर नाम से गुजरना चाहता हूं, और फिर फ़ोल्डर पथ की गणना करता हूं। इस regex का उपयोग करना सही काम करता है, जबकि dirname फ़ंक्शन ने पैरेंट फ़ोल्डर को वापस कर दिया है जब मैं एक फ़ोल्डर इनपुट करता हूं।
ऐनीएजाइल

8
हालांकि, अगर $ VAR में कोई पथ जानकारी नहीं है, तो $ {VAR% / *} / परीक्षण $ VAR / परीक्षण के बराबर एक अप्रत्याशित मान पैदा करता है जबकि $ (dirname $ VAR) / .est का अधिक अनुमानित और उचित मूल्य उत्पन्न करेगा। यह एक बड़ी बात है क्योंकि पूर्व फाइलनाम को एक निर्देशिका के रूप में मानने का प्रयास करेगा जबकि उत्तरार्द्ध ठीक होगा।
डेविमरॉन

19

संबंधित नोट पर, यदि आपके पास केवल फ़ाइल नाम या संबंधित पथ है, तो dirnameअपने आप मदद नहीं करेगा। मेरे लिए, जवाब समाप्त हो रहा है readlink

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

आप केवल निर्देशिका प्राप्त करने के लिए दोनों को जोड़ सकते हैं।

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

1
यदि एक से अधिक पथ घटक मौजूद नहीं हैं, तो आपको readlink -m "$fname"पुनरावर्ती रूप से दिए गए नाम को कैनोनिकलाइज़ करने के लिए उपयोग करना चाहिए
EDkan

7

यदि आप लक्ष्य फ़ाइलों को प्रतीकात्मक लिंक होने की परवाह करते हैं, तो सबसे पहले आप इसकी जांच कर सकते हैं और मूल फ़ाइल प्राप्त कर सकते हैं। अगर नीचे दिए गए क्लॉज़ से आपको मदद मिल सकती है।

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

5

मैं इसके साथ खेल रहा था और एक विकल्प के साथ आया था।

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

$ DIR=`echo $VAR |xargs dirname`

$ echo $DIR
/home/me/mydir

मुझे जो हिस्सा पसंद आया वह यह है कि पेड़ को बैकअप देना आसान था:

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

$ echo $DIR
/home

1

यहाँ एक स्क्रिप्ट है जिसका उपयोग मैंने पुनरावर्ती ट्रिमिंग के लिए किया था। $ 1 को उस निर्देशिका से बदलें जो आप चाहते हैं, निश्चित रूप से।

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

सबसे पहले, मैंने /खाली जगह ( ) के साथ प्रतिस्थापित किया है । फिर, मैंने किसी भी खाली जगह ( ) से पहले सभी पात्रों को हटा दिया । अंत में, मैंने पहला पात्र हटा दिया जो खाली जगह है ( )।

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

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

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

जहाँ आपको new_path = के साथ पूर्ण पथ मिलता है $(dirname ${BASH_SOURCE[0]})। आप cd new_path के साथ वर्तमान निर्देशिका बदलते हैं और फिर वर्तमान निर्देशिका के pwdलिए पूर्ण पथ प्राप्त करने के लिए चलाते हैं ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.