INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml | head -1 | xargs basename`
मैं दूसरी कमांड को निष्पादित करना चाहता था ( head -1
) केवल तभी जब पहली कमांड सफल हो। मैं इस आदेश को कैसे सुधारूं?
INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml | head -1 | xargs basename`
मैं दूसरी कमांड को निष्पादित करना चाहता था ( head -1
) केवल तभी जब पहली कमांड सफल हो। मैं इस आदेश को कैसे सुधारूं?
जवाबों:
इसे इस्तेमाल करे:
INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml | head -1 | xargs -r basename`
ध्वज को पास xargs
करने से -r
यह केवल तभी चल सकेगा basename
जब मानक इनपुट ( head -1
) से कम से कम एक आइटम को पढ़ता है ।
head -1
चलेगा, लेकिन आप इससे कोई आउटपुट नहीं देखेंगे या कैप्चर नहीं करेंगे।
इसके अलावा, यदि आप उपयोगकर्ता से कोई त्रुटि आउटपुट नहीं देखना चाहते हैं, तो आप 's stderr' स्ट्रीम को ls
पुनर्निर्देशित कर सकते हैं ।ls
/dev/null
INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml 2> /dev/null | head -1 | xargs -r basename`
यह भी ध्यान दें कि मैंने उद्धरण चिह्नों को चारों ओर जोड़ा $MY_DIR
। इस तरह, यदि $MY_DIR
रिक्त स्थान होते हैं, तो कमांड विफल नहीं होगी ।
यदि आप आधुनिक आवरण जैसे बैश का उपयोग कर रहे हैं, तो आपको $( )
बैकटिक्स के बजाय कैप्चर शेल का उपयोग करना चाहिए । आपको अपने चर की शैली को बदलने पर भी विचार करना चाहिए। आपको आम तौर पर लिपियों में सभी-अपरकेस चर नामों का उपयोग करने से बचना चाहिए। वह शैली आम तौर पर आरक्षित और पर्यावरण चर के लिए आरक्षित है।
input_file=$(ls -rt "$my_dir"/FILE.*.xml 2> /dev/null | head -1 | xargs -r basename)
ls -rt GLOB 2>/dev/null | head -n1 | xargs -r basename
काम करता है।
एक पाइप लाइन में, सभी कमांड शुरू होते हैं और समवर्ती रूप से चलते हैं, एक के बाद एक नहीं। तो आपको आउटपुट को कहीं स्टोर करने की आवश्यकता है।
if ls_output=$(ls -rtd -- "$MY_DIR"/FILE.*.xml); then
first_file=$(printf '%s\n' "$ls_output" | head -n 1)
first_file_name=$(basename -- "$first_file")
fi
ध्यान दें कि यह मानती है कि फ़ाइल नाम में न्यूलाइन वर्ण नहीं हैं। उपयोग करने xargs
से रिक्त पात्रों, एकल और दोहरे उद्धरण और बैकस्लैश के साथ समस्याओं का भी अर्थ होगा। निर्गत चर को छोड़ने से अंतरिक्ष, टैब और वाइल्डकार्ड वर्णों की समस्या होगी। भूलने --
का मतलब होगा कि फ़ाइल नाम के साथ समस्याएँ शुरू होती हैं -
।
zsh
वर्णों पर उन प्रतिबंधों के बिना सबसे पुरानी फ़ाइल का बेसनेम प्राप्त करने के लिए (एक कमांड के तर्कों के सीमित आकार की समस्या से भी बचा जाता है):
first_file_name=($MY_DIR/FILE.*.xml(Om[1]:t))
यदि कोई मेल नहीं है, तो वह आदेश विफल हो जाएगा और स्क्रिप्ट को निरस्त कर देगा। आप भी कर सकते हैं:
first_file_name=($MY_DIR/FILE.*.xml(NOm[1]:t))
जिस स्थिति में first_file_name
सरणी में 1 तत्व होगा यदि मैच या 0 है तो नहीं। आप तब कर सकते हैं:
if (($#first_file_name)); then
printf 'Match: %s\n' $first_file_name
else
echo >&2 No match
fi
निर्देशिका में नवीनतम संशोधित फ़ाइल खोजें:
latest() {
local file path=${1:-.} ext=${2-} latest
for file in "${path%/}"/*"$ext"; do
[[ $file -nt $latest ]] && latest=$file
done
[[ $latest ]] && printf '%s\n' "$latest"
}
उपयोग: latest [directory/path/ [.extension]]
कॉल आउट करने के बजाय basename
, पैरामीटर विस्तार का उपयोग करें।
in_file=$(latest in/my/dir .xml)
base_fn=${in_file##*/} base_fn=${base_fn%.*}
इन सामग्रियों वाली निर्देशिका में:
foo.xml bar.xml baz.xml newest.xml
Base_fn वैरिएबल की सामग्री इस प्रकार होगी: newest
अपने अनुरोध के उद्देश्य की पूर्ति के लिए इसका उचित उपयोग करें:
check_dir=/path/to/check
check_ext=.xml
if in_file=$(latest "$check_dir" "$check_ext"); then
base_fn=${in_file##*/} base_fn=${base_fn%.*}
else
printf '%s\n' "No file found in $check_dir" >&2
fi
संपादित करें: प्रश्न की समीक्षा करने पर, मैंने महसूस किया है कि ls
विचाराधीन कमांड एक निर्देशिका में सबसे पुरानी फ़ाइल की तलाश में है। इसी फ़ंक्शन को फिर से नाम दिया जा सकता है oldest
और इसके [[ $file -ot $oldest ]] && oldest=$file
बजाय समान प्रभाव प्राप्त कर सकते हैं। किसी भी भ्रम के लिए माफी।
ध्यान देने वाली महत्वपूर्ण बात यह है कि आप पूरी तरह से मानव जाति में कभी भी किसी भी परिस्थिति में, ls के आउटपुट को पार्स नहीं करना चाहिए। कभी नहीँ।
ls
-based दृष्टिकोण के विपरीत , यदि सीमलिंक हैं, तो सीमलिंक के लक्ष्य के संशोधन समय पर विचार किया जाएगा ( उसी व्यवहार को प्राप्त -L
करने के ls
लिए विकल्प जोड़ें )।
मुझे लगता है कि यहाँ सबसे अच्छा विकल्प है:
ls -rf $MY_DIR/FILE.*.xml
if [ $? -eq 0 ]; then
INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml|head -1|xargs basename `
else
echo "Error!"
fi
अगर कोई फाइल नहीं है, तो ls का रिटर्न कोड 2 है, लेकिन अगर यह पाया जाता है कि कुछ फाइल 0 होगी।
ls
असफल नहीं होगा।