ग्लोब पैटर्न से परिभाषित चर के साथ बैश प्रतिस्थापन


10

नीचे दिए गए उदाहरण मुद्दे की व्याख्या करते हैं। FILENAMEजब प्रतिस्थापन का उपयोग करके प्रतिध्वनि और पैटर्न के रूप में माना जाता है तो सही ढंग से क्यों मुद्रित किया जाता है?

#!/bin/bash

FILEPATH_WITH_GLOB="/home/user/file_*"
FILENAME=$(basename "$FILEPATH_WITH_GLOB")
echo $FILENAME                #file_1234
echo ${FILENAME:1:5}          #ile_*   <---why is this not ile_1

जवाबों:


15
FILEPATH_WITH_GLOB="/home/user/file_*"

अब, FILEPATH_WITH_GLOBशामिल है/home/user/file_*

FILENAME=$(basename "$FILEPATH_WITH_GLOB")

FILENAMEहोता है file_*

echo $FILENAME                #file_1234

$FILENAMEसूची के संदर्भ में अयोग्य होने के कारण, यह विस्तार विभाजन + ग्लोब ऑपरेटर से गुजरता है, इसलिए यह मेल खाने वाली फ़ाइल की सूची में विस्तारित होता है: फ़ाइल नाम पीढ़ी पैरामीटर विस्तार पर किया जाता है ।

echo ${FILENAME:1:5}          #ile_*   <---why is this not ile_1

यह अभी भी सूची के संदर्भ में एक निर्विवाद पैरामीटर विस्तार है, इसलिए अभी भी विभाजन + ग्लोब से गुजरता है। हालाँकि, यहाँ ile_*पैटर्न किसी भी फाइल से मेल नहीं खाता है, इसलिए यह इसके बजाय अपने आप फैलता है।

आप शायद यहाँ क्या चाहते हैं:

shopt -s nullglob # have globs expand to nothing when they don't match
set -- /home/user/file_* # expand that pattern into the list of matching 
                         # files in $1, $2...
for file do  # loop over them
  filename=$(basename -- "$file")
  printf '%s\n' "$filename" "${filename:1:5}"
done

या आप उन्हें एक सरणी में संग्रहीत कर सकते हैं:

shopt -s nullglob
files=(/home/user/file_*)

यदि आप केवल पहले मैच के बारे में परवाह करते हैं, या आप जानते हैं कि केवल एक ही मैच है, तो आप उस फ़ाइल का उल्लेख कर सकते हैं $filesbashयह आमतौर पर कष्टप्रद व्यवहार है जो सरणी के सभी तत्वों (विरासत में मिला व्यवहार , निश्चित ) के बजाय $filesफैलता है , लेकिन यहाँ, यह एक बार के लिए एक वांछित व्यवहार होगा।${files[0]}kshzsh


स्पष्टीकरण के लिए धन्यवाद। FILEPATH_WITH_GLOB=`echo /home/user/file_*` आपके स्पष्टीकरण के बाद वर्कअराउंड करने का प्रबंधन ।
TheMeaningfulEngineer

@Alan, इसे संबोधित करने का गलत तरीका है। आप यहाँ एक सरणी का उपयोग करना चाहते हैं। या तो मेरे उदाहरण के रूप में स्थितीय मापदंड ($ 1, $ 2 ...) या एक bashसरणी जैसे files=(/home/user/file_*):।
स्टीफन चेज़लस

(और सभी ऊपरी-केस चर वास्तव में पर्यावरण चर के लिए आरक्षित होने echoचाहिए , मनमाने डेटा के लिए उपयोग नहीं किया जाना चाहिए, चर को संदर्भ सूची में अयोग्य नहीं छोड़ा जाना चाहिए)।
स्टीफन चेज़लस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.