जवाबों:
basename
GNU कोरुटिल्स इस काम को करने में आपकी मदद कर सकते हैं:
$ basename /root/video.mp4
video.mp4
यदि आप पहले से ही फाइल का विस्तार जानते हैं, तो आप इसे हटाने के basename
लिए सिंटैक्स का उपयोग कर सकते हैं basename NAME [SUFFIX]
:
$ basename /root/video.mp4 .mp4
video
या किसी अन्य विकल्प का उपयोग करके अंतिम बिंदु के बाद सब कुछ काट दिया जाएगा sed
:
$ basename /root/video.old.mp4 | sed 's/\.[^.]*$//'
video.old
निम्नलिखित में से किसी भी तरीके का उपयोग करें:
out_file="${in_file##*/}"
out_file="$(basename $in_file)"
out_file="$(echo $in_file | sed 's=.*/==')"
out_file="$(echo $in_file | awk -F"/" '{ print $NF }')"
ps। आपको एक ही स्ट्रिंग मिलती है क्योंकि आपके स्टेटमेंट \(.*\.\)
में शुरुआत से लेकर डॉट ( /root/video.
) तक स्ट्रिंग से मेल खाता है और फिर आप मैन्युअल रूप से जोड़ते हैं .mp4
जो कि मूल स्ट्रिंग के समान है। आपको s=.*\([^/]*\)=\1=
इसके बजाय उपयोग करना चाहिए ।
अद्यतन: (पहले एक अब तय हो गया है)
बिना विस्तार के एकमात्र फ़ाइल नाम प्राप्त करने के लिए:
out_file="$(echo $in_file | sed 's=.*/==;s/\.[^.]*$/.new_ext/')"
out_file="$(echo $in_file | sed 's=\([^/]*\)\.[^./]*$=\1.new_ext=')"
out_file="$(echo $in_file | awk -F"/" '{ gsub (/\.[^/.]*$/,".new_ext",$NF);print $NF }'
my.file.tar.gz
।
sed
और में एक लापता डॉट प्रतीक था awk
। फिक्स्ड। धन्यवाद।
रेगेक्स का उपयोग करने के मूल सिद्धांतों में से एक यह है कि वाइल्ड कार्ड निर्दिष्ट करते समय पैटर्न स्वभाव से लालची होते हैं। जबकि @uloBasEI द्वारा प्रस्तावित उत्तर निश्चित रूप से एक कामकाजी उत्तर है, इसके लिए भी बेसन कमांड के उपयोग की आवश्यकता होती है। @ शिक्सों से मूल प्रश्न केवल sed का उपयोग करके समाधान का अनुरोध करता है।
जारी रखने से पहले, यह जानना हमेशा मददगार होता है कि सीड का कौन सा संस्करण लक्ष्य है। मैं BSD मान रहा हूं (जैसा OSX के साथ शिप किया गया है)।
सबसे पहले, मूल प्रश्न में प्रस्तावित पैटर्न काम नहीं करता है क्योंकि यह इनपुट स्ट्रिंग की शुरुआत से लेकर अंतिम डॉट तक और सब कुछ कैप्चर करता है। एंकरों के बिना, यह खोज बाएं से दाएं सब कुछ निगल जाएगी। "/ 1" का मिलान पैटर्न, इसलिए, अंतिम डॉट सहित सब कुछ है। यहां तक कि कई डॉट्स के साथ एक फ़ाइल नाम पूरे निगल लिया जाएगा। वांछित परिणाम बिल्कुल नहीं।
पहला कदम पैटर्न की पहचान के लिए एक रणनीति स्थापित करना है। यहाँ, आप फ़ाइल नाम के बाईं ओर सब कुछ निकालना चाहते हैं (हम बाद में विस्तार से निपटेंगे):
out_file="$(echo $in_file | sed 's/^\(\/.*\/\)*.*/\1/')"
खोज स्ट्रिंग की शुरुआत से मेल खाती है। यह "/.*" शून्य या अधिक समय के पैटर्न से मेल खाता है और बाद में सब कुछ हटा देता है। हम "\" के साथ मिलान किए गए पैटर्न प्रिंट करते हैं। हम विश्व स्तर पर खोज नहीं कर रहे हैं; हम ^ एंकर को निर्दिष्ट करके स्ट्रिंग की शुरुआत से खोज कर रहे हैं।
हमें "-E" विकल्प को सक्षम करके बेहतर स्पष्टता मिलती है ताकि हमें कोष्ठक से बचना न पड़े:
out_file="$(echo $in_file | sed -E 's/^(\/.*\/)*.*/\1/')"
इसलिए अब हमारे पास बाईं ओर का भाग है। चलो दाईं ओर का हिस्सा जोड़ते हैं। ध्यान दें कि हमें बाएं हिस्से को एक पैटर्न के रूप में रखना होगा क्योंकि हम यह निर्दिष्ट कर सकते हैं कि यह शून्य या अधिक बार दिखाई देता है। अब हम केवल दाईं ओर भाग के लिए एक पैटर्न जोड़ रहे हैं:
out_file="$(echo $in_file | sed -E 's/^(\/.*\/)*(.*)/\2/')"
हम केवल दूसरे मैच का प्रिंट आउट लेते हैं, जिससे सब कुछ छूट जाता है लेकिन फ़ाइल नाम। लेकिन हमें अभी भी फ़ाइल नाम एक्सटेंशन को हटाने की आवश्यकता है।
out_file="$(echo $in_file | sed -E 's/^(\/.*\/)*(.*)\..*$/\2/')"
अंत में "$" वैकल्पिक है।
अंत में, नए एक्सटेंशन को जोड़ने के लिए आप बस इतना संशोधित करें:
out_file="$(echo $in_file | sed -E 's/^(\/.*\/)*(.*)\..*$/\2.mp4/')"
एक अतिरिक्त अनुकूलन सापेक्ष पथ को संभालने के लिए पहला फ़ॉरवर्ड स्लैश वैकल्पिक बनाना है:
out_file="$(echo $in_file | sed -E 's/^([\/]?.*\/)*(.*)\..*$/\2.mp4/')"
बेसन की जगह एक सेडान पैटर्न की तलाश में मैं आलसी होकर इस सवाल पर आया था । मैं एक छीन सिस्टम पर काम कर रहा हूं जिसमें वह कमांड स्थापित नहीं है।
sed 's/\.[^.]*$//'
आप के रूप में, के लिए (छुपा) असफल हो जायेगी.filename
और.
और..
निर्देशिका