एक पूर्ण पथ बनाने के लिए दो तारों को कैसे मिलाएं


93

मैं एक बैश स्क्रिप्ट लिखने की कोशिश कर रहा हूं। इस स्क्रिप्ट में मैं चाहता हूं कि उपयोगकर्ता एक निर्देशिका का पथ दर्ज करें। फिर मैं इस तार के अंत में कुछ तार जोड़ना चाहता हूं और कुछ उपनिर्देशिकाओं के लिए एक रास्ता बनाना चाहता हूं। उदाहरण के लिए मान लें कि उपयोगकर्ता इस तरह एक स्ट्रिंग में प्रवेश करता है:

/home/user1/MyFolder

अब मैं इस निर्देशिका में 2 उपनिर्देशिकाएँ बनाना चाहता हूँ और वहाँ कुछ फ़ाइलों की प्रतिलिपि बनाना चाहता हूँ।

/home/user1/MyFolder/subFold1
/home/user1/MyFolder/subFold2

मैं यह कैसे कर सकता हूँ?


1
अब तक तुमने क्या प्रयास किये हैं? इसके अलावा, उपयोगकर्ता से इनपुट प्राप्त करने के बारे में आपके प्रश्न का हिस्सा है, और दूसरा भाग पथ के निर्माण के बारे में है? या सिर्फ रास्ता?
लेवॉन

जवाबों:


133

POSIX मानक यह बताता है कि फ़ाइल नाम में कई /को एकल के रूप में माना जाता है /। इस प्रकार के //dir///subdir////fileरूप में ही है /dir/subdir/file

इस तरह के रूप में एक पूर्ण पथ का निर्माण करने के लिए दो तारों को जोड़ना सरल है:

full_path="$part1/$part2"

11
सिवाय अगर $ part1 खाली स्ट्रिंग हो सकता है।
ट्यूरे लौरिनोली

1
@TuureLaurinolli मुझे समझ नहीं आ रहा है कि आप कहाँ से आ रहे हैं। उपर्युक्त संघटन के परिणामस्वरूप अभी भी एक वैध मार्ग होगा। पथ मौजूद नहीं हो सकता है, लेकिन यह अभी भी मान्य होगा। जैसे। "" + "/" + "Documents"देता है "/Documents"
टिब्बा

17
यदि भाग स्वयं सापेक्ष पथ हैं, और part1 खाली हो सकता है, तो परिणाम सापेक्ष से निरपेक्ष पथ में बदल सकता है।
ट्यूर लॉरिनोली

2
@TuureLaurinolli तब आप बस ./सामने जोड़ सकते हैं । लेकिन हो सकता है कि उपयोगकर्ता निरपेक्ष पथ को प्राप्त करना चाहता हो। अन्यथा वे बस ./सामने वाले को जोड़ सकते थे ताकि वह रिश्तेदार होने के लिए मजबूर कर सके। यह भी ध्यान दें कि "$path1/./$path2"जैसा है वैसा ही है "$path1/$path2"
yyny

41
#!/bin/bash

read -p "Enter a directory: " BASEPATH

SUBFOLD1=${BASEPATH%%/}/subFold1
SUBFOLD2=${BASEPATH%%/}/subFold2

echo "I will create $SUBFOLD1 and $SUBFOLD2"

# mkdir -p $SUBFOLD1
# mkdir -p $SUBFOLD2

और यदि आप रीडलाइन का उपयोग करना चाहते हैं तो आप पूरा कर लें और वह सब, -eकॉल में जोड़ें read:

read -e -p "Enter a directory: " BASEPATH

1
दुर्भाग्य से, यह तब काम नहीं करता है जब बासपेट खाली है। मुझे कुछ ऐसा चाहिए, जो केवल एक को जोड़ता है / जब वह पहले से ही स्लैश का अंत नहीं करता है और खाली नहीं है। इस प्रकार, जब यह एक कानूनी फ़ाइल नाम चरित्र पर समाप्त होता है।
कार्लो वुड

16

क्या आप चाहते हैं कि आपके रास्ते की उपलब्धि के हिस्से को बस संक्षिप्त नहीं करेंगे?

$ base="/home/user1/MyFolder/"
$ subdir="subFold1"
$ new_path=$base$subdir
$ echo $new_path
/home/user1/MyFolder/subFold1

फिर आप आवश्यकतानुसार फ़ोल्डर / निर्देशिका बना सकते हैं।

एक सम्मेलन /(जैसे /home/) के साथ निर्देशिका पथों को समाप्त करना है क्योंकि / से शुरू होने वाले पथ को रूट निर्देशिका के साथ भ्रमित किया जा सकता है। यदि एक //मार्ग में डबल स्लैश ( ) का उपयोग किया जाता है, तो यह अभी भी सही है। लेकिन, यदि कोई स्लैश का उपयोग चर पर नहीं किया जाता है, तो यह गलत होगा (जैसे /home/user1/MyFoldersubFold1)।


3
मुझे यह संदेश क्यों मिला: Myscript.sh: पंक्ति 4: / होम / उपयोगकर्ता 1 / MyFolder / subFold1: एक निर्देशिका है
हकीम

2
आप पथ से / को याद कर रहे हैं। लक्ष्य इनलाइन है /home/user1/MyFolder/subFold1 इसलिए आपको इनलाइन की आवश्यकता होगी new_path=$base/$subdir। लेकिन फिर आप क्या करते हैं अगर दिए गए रास्ते में एक अनुगामी '/' शामिल है?
थ्रसी

1
@ थ्रसी सिर्फ अनुगामी '/' को या तो उपडिर चर में जोड़ता है या newpath=$base/$subdir/आप इसे सीधे कमांड लाइन पर खेल सकते हैं
user12345

3
@ user12345, हां ... अभी भी समाधान गलत से ऊपर है।
तृप्ति

5

निम्नलिखित स्क्रिप्ट एक सापेक्ष पथ (SUBDIR) के साथ कई (रिश्तेदार / निरपेक्ष) पथ (BASEPATH) को पूरा करता है:

shopt -s extglob
SUBDIR="subdir"
for BASEPATH in '' / base base/ base// /base /base/ /base//; do
  echo "BASEPATH = \"$BASEPATH\" --> ${BASEPATH%%+(/)}${BASEPATH:+/}$SUBDIR"
done

जिसका आउटपुट है:

BASEPATH = "" --> subdir
BASEPATH = "/" --> /subdir
BASEPATH = "base" --> base/subdir
BASEPATH = "base/" --> base/subdir
BASEPATH = "base//" --> base/subdir
BASEPATH = "/base" --> /base/subdir
BASEPATH = "/base/" --> /base/subdir
BASEPATH = "/base//" --> /base/subdir

shopt -s extglobकेवल BASEPATH कई स्लैश पर समाप्त करने के लिए (जो शायद बकवास है) की अनुमति देने के लिए आवश्यक है। विस्तारित दस्ताने के बिना आप बस उपयोग कर सकते हैं:

echo ${BASEPATH%%/}${BASEPATH:+/}$SUBDIR

जिसके परिणामस्वरूप कम साफ लेकिन अभी भी काम कर रहा है:

BASEPATH = "" --> subdir
BASEPATH = "/" --> /subdir
BASEPATH = "base" --> base/subdir
BASEPATH = "base/" --> base/subdir
BASEPATH = "base//" --> base//subdir
BASEPATH = "/base" --> /base/subdir
BASEPATH = "/base/" --> /base/subdir
BASEPATH = "/base//" --> /base//subdir

1

मैं अपनी शेल स्क्रिप्ट के साथ काम कर रहा था, जिसमें आपको कुछ चीजें मिलाने की जरूरत है जैसे आप करते हैं।

बात यह है, दोनों तरह की राह

/data/foo/bar

/data/foo/bar/ 

वैध हैं।

अगर मैं इस तरह से एक फ़ाइल संलग्न करना चाहते हैं

/data/foo/bar/myfile

ऐसी स्थिति को संभालने के लिए शेल में कोई मूल विधि (जैसे कि ओ.एस.पी.थोइन (अजगर में)) नहीं थी।

लेकिन मुझे एक तरकीब सूझी

उदाहरण के लिए, आधार पथ शेल चर में संग्रहित किया गया था

BASE=~/mydir

और अंतिम फ़ाइल नाम जिसे आप जोड़ना चाहते थे

FILE=myfile

फिर आप इस तरह से अपना नया पथ असाइन कर सकते हैं

NEW_PATH=$(realpath ${BASE})/FILE

और फिर आप मिल जाएंगे

$ echo $NEW_PATH

/path/to/your/home/mydir/myfile

कारण सरल है, "realpath" कमांड हमेशा आवश्यक होने पर आपके लिए समाप्ति स्लैश ट्रिम कर देगा


0
#!/usr/bin/env bash

mvFiles() {
    local -a files=( file1 file2 ... ) \
             subDirs=( subDir1 subDir2 ) \
             subDirs=( "${subDirs[@]/#/$baseDir/}" )

    mkdir -p "${subDirs[@]}" || return 1

    local x
    for x in "${subDirs[@]}"; do
        cp "${files[@]}" "$x"
    done
}



main() {
    local baseDir
    [[ -t 1 ]] && echo 'Enter a path:'
    read -re baseDir
    mvFiles "$baseDir"
}

main "$@"

0

यह खाली डायर के लिए काम करना चाहिए (आपको यह जांचने की आवश्यकता हो सकती है कि क्या दूसरा तार शुरू होता है /जिसे पूर्ण निरपेक्ष के रूप में माना जाना चाहिए?)

#!/bin/bash

join_path() {
    echo "${1:+$1/}$2" | sed 's#//#/#g'
}

join_path "" a.bin
join_path "/data" a.bin
join_path "/data/" a.bin

आउटपुट:

a.bin
/data/a.bin
/data/a.bin

संदर्भ: शेल पैरामीटर विस्तार

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