Sed का उपयोग करके केवल फ़ाइल नाम कैसे प्राप्त करें


18

मैं केवल फ़ाइल नाम का उपयोग कैसे कर सकता हूँ sed? मैंने यह किया है

out_file=$(echo $in_file|sed "s/\(.*\.\).*/\1mp4/g")

लेकिन मुझे रास्ता भी मिलता है /root/video.mp4 , और मुझे केवल यही चाहिए video.mp4

जवाबों:


28

basenameGNU कोरुटिल्स इस काम को करने में आपकी मदद कर सकते हैं:

$ 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

3
का उपयोग करते हुए sed 's/\.[^.]*$//'आप के रूप में, के लिए (छुपा) असफल हो जायेगी .filenameऔर .और ..निर्देशिका
Peter.O

9

सबसे आसान समाधान अंतिम उपस्थिति तक सब कुछ हटा देता है /:

echo /root/video.mp4 | sed 's/.*\///'


5

निम्नलिखित में से किसी भी तरीके का उपयोग करें:

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 }'

लेकिन उन तरीकों में से किसी के साथ मुझे प्रारूप के साथ फ़ाइल नाम मिलता है और मुझे केवल फ़ाइल नाम प्राप्त करने और मैन्युअल रूप से एक नया प्रारूप डालने की आवश्यकता है।
6

आह, यह समझ में आता है। मैंने अपना उत्तर अपडेट कर दिया है।
भीड़

@rush: नाम की फ़ाइल के लिए किनारे मामले होंगे, जैसे my.file.tar.gz
donothingsuccessfully

@donothingsuccessfully अंतिम sedऔर में एक लापता डॉट प्रतीक था awk। फिक्स्ड। धन्यवाद।
भीड़

4

रेगेक्स का उपयोग करने के मूल सिद्धांतों में से एक यह है कि वाइल्ड कार्ड निर्दिष्ट करते समय पैटर्न स्वभाव से लालची होते हैं। जबकि @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/')"

बेसन की जगह एक सेडान पैटर्न की तलाश में मैं आलसी होकर इस सवाल पर आया था । मैं एक छीन सिस्टम पर काम कर रहा हूं जिसमें वह कमांड स्थापित नहीं है।

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