Awk रूट का उपयोग करके अंतिम फ़ील्ड प्राप्त करें


99

मैं awkउस फ़ाइल का नाम प्राप्त करने के लिए उपयोग करने की कोशिश कर रहा हूं जिसे फ़ाइल को पूर्ण पथ दिया गया है।
उदाहरण के लिए, जब दिया गया इनपुट पथ /home/parent/child/filenameमैं प्राप्त करना चाहता filename हूं, तो मैंने कोशिश की है:

awk -F "/" '{print $5}' input

जो पूरी तरह से काम करता है।
हालाँकि, मैं हार्ड कोडिंग कर रहा हूँ $5जो कि मेरे इनपुट में निम्न संरचना है तो गलत होगा:

/home/parent/child1/child2/filename

तो एक सामान्य समाधान के लिए हमेशा अंतिम फ़ील्ड (जो फ़ाइल नाम होगा) लेने की आवश्यकता होती है ।

क्या यह एक सरल तरीका है जो awk root फंक्शन के साथ होता है?


2
जैसा कि किसी ने बताया कि basenameऐसा करने का आधिकारिक तरीका है, इसके awkलिए इसका उपयोग करना हल्का नहीं है। : D
कश्यप

जवाबों:


206

इस तथ्य का उपयोग करें कि awkफ़ील्ड विभाजक के आधार पर फ़ील्ड्स में लाइनों को विभाजित करता है, जिसे आप परिभाषित कर सकते हैं। इसलिए, /आप कह सकते हैं कि क्षेत्र विभाजक को परिभाषित करना :

awk -F "/" '{print $NF}' input

जैसा NFकि वर्तमान रिकॉर्ड के क्षेत्रों की संख्या को दर्शाता है, मुद्रण का $NFअर्थ है पिछले एक को प्रिंट करना।

तो इस तरह एक फ़ाइल दी:

/home/parent/child1/child2/child3/filename
/home/parent/child1/child2/filename
/home/parent/child1/filename

यह आउटपुट होगा:

$ awk -F"/" '{print $NF}' file
filename
filename
filename

3
यह पूरी तरह से काम करता है। मैं $ NF चर के बारे में नहीं सोचा था। आपके तत्काल सरल और प्रभावी उत्तर के लिए धन्यवाद।
मारी

6
तपस्या के लिए, एक का उपयोग करें $(NF-1)
इताची

1
कुछ डॉकटर कमांड के साथ काम करने के लिए एक स्क्रिप्ट लिख रहा था और इसने यह चाल चली। धन्यवाद!
हरलीन

30

इस मामले में इसका उपयोग basenameकरना बेहतर है awk:

 $ basename /home/parent/child1/child2/filename
 filename

4
@ मारी FYI dirname विपरीत और स्ट्रिप्स फ़ाइल को पथ नहीं करता है।
क्रिस सेमोर


5

यदि आप एक पर्ल समाधान के लिए खुले हैं, तो यहां फेडोरक्वी के awk समाधान के समान है:

perl -F/ -lane 'print $F[-1]' input

-F//फ़ील्ड विभाजक के रूप में निर्दिष्ट करता
$F[-1]है, @Fऑटोसप्लिट सरणी में अंतिम तत्व है


1
धन्यवाद। इससे मुझे आखिरी लेकिन एक क्षेत्र हासिल करने में मदद मिली। perl -F "/" -लेन 'प्रिंट $ F [-2]' इनपुट
राइडरचैप

पाइप इनपुट से प्राप्त होने पर यह मेरे लिए काम करता है। पूरी तरह से पर्ल के बारे में भूल गया।
क्रिस्टोफर

3

यह बेसन जवाब के लिए एक टिप्पणी होनी चाहिए, लेकिन मैं पर्याप्त बिंदु नहीं है।

यदि आप दोहरे उद्धरण चिह्नों का उपयोग basenameनहीं करते हैं , तो उस स्थान के साथ काम नहीं करेंगे जहां अंतरिक्ष वर्ण है:

$ basename /home/foo/bar foo/bar.png
bar

ठीक है उद्धरण के साथ ""

$ basename "/home/foo/bar foo/bar.png"
bar.png

फ़ाइल उदाहरण

$ cat a
/home/parent/child 1/child 2/child 3/filename1
/home/parent/child 1/child2/filename2
/home/parent/child1/filename3

$ while read b ; do basename "$b" ; done < a
filename1
filename2
filename3

3

मुझे पता है कि मैं इस पर 3 साल की देरी से हूँ लेकिन .... आपको पैरामीटर विस्तार पर विचार करना चाहिए, यह बिल्ट-इन और तेज़ है।

यदि आपका इनपुट एक var में है, तो हम कहते हैं, $ var1, बस करो ${var1##*/}। नीचे देखें

$ var1='/home/parent/child1/filename'
$ echo ${var1##*/}
filename
$ var1='/home/parent/child1/child2/filename'
$ echo ${var1##*/}
filename
$ var1='/home/parent/child1/child2/child3/filename'
$ echo ${var1##*/}
filename

2

5 साल की देरी से, मुझे पता है, सभी प्रस्तावों के लिए धन्यवाद, मैं इसे निम्नलिखित तरीके से करता था:

$ echo /home/parent/child1/child2/filename | rev | cut -d '/' -f1 | rev
filename

खुशी है कि वहाँ बेहतर शिष्टाचार नोटिस कर रहे हैं


-1

आप भी उपयोग कर सकते हैं:

    sed -n 's/.*\/\([^\/]\{1,\}\)$/\1/p'

या

    sed -n 's/.*\/\([^\/]*\)$/\1/p'

1
इस बिंदु पर किसी ने भी इस जवाब को आगे नहीं बढ़ाया, शायद इसलिए कि यह तुलनात्मक रूप से बेहद :) :)
जोसिप रॉडिन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.