Awk সাবস্ট্রটার ব্যবহার করে শেষ ক্ষেত্র পান


105

আমি awkফাইলটির পরম পথ দিয়ে কোনও ফাইলের নাম পাওয়ার জন্য ব্যবহার করার চেষ্টা করছি ।
উদাহরণস্বরূপ, যখন ইনপুট পাথ দেওয়া /home/parent/child/filenameহবে তখন filename আমি চেষ্টা করতে চাই :

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

যা নিখুঁতভাবে কাজ করে।
তবে, আমি কঠোর কোডিং করছি $5যা আমার ইনপুটটির নিম্নলিখিত কাঠামোটি থাকলে ভুল হবে:

/home/parent/child1/child2/filename

সুতরাং একটি জেনেরিক সমাধানের জন্য সর্বদা সর্বশেষ ক্ষেত্র গ্রহণ করা প্রয়োজন (যা ফাইলের নাম হবে)।

অ্যাডক সাবস্ট্রাস্ট ফাংশনটির সাথে এটি করার সহজ উপায় কি আছে?


4
যেহেতু কেউ এটির আধ্যাত্মিক উপায়টি ব্যবহার করে দেখিয়েছেন basename, awkএটির জন্য ব্যবহার করা একে হালকা করে রাখা ভাল নয়। : ডি
কাশ্যপ

উত্তর:


216

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

4
এটি পুরোপুরি কাজ করে। আমি $ NF ভেরিয়েবল সম্পর্কে ভাবিনি। আপনার তাত্ক্ষণিক সহজ এবং কার্যকর উত্তরের জন্য ধন্যবাদ।
মারি

6
পেনাল্ট একের জন্য, ব্যবহার করুন $(NF-1)
Itachi

4
কিছু ডকার কমান্ডের সাথে কাজ করার জন্য একটি স্ক্রিপ্ট লিখছিল এবং এটি কৌশলটি করেছিল। ধন্যবাদ!
হারলিন

31

এই ক্ষেত্রে basenameপরিবর্তে ব্যবহার করা ভাল awk:

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

4
@ মারি এফওয়াইআই dirname বিপরীতে কাজ করে এবং স্ট্রিপগুলি ফাইলটি করে না।
ক্রিস সিমুর


5

যদি আপনি কোনও পার্ল সমাধানের জন্য উন্মুক্ত হন তবে এখানে ফেডোরকির অজানা সমাধানের অনুরূপ:

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

-F//ক্ষেত্র বিভাজক হিসাবে অটোস্প্লিট অ্যারেতে
$F[-1]সর্বশেষ উপাদান হিসাবে উল্লেখ করা হয়@F


4
ধন্যবাদ এটি আমাকে শেষ তবে একটি ক্ষেত্র পেতে সহায়তা করেছিল। পার্ল-এফ "/" -লেন 'প্রিন্ট করুন $ এফ [-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 বছর দেরি করছি কিন্তু .... আপনার পরামিতি প্রসার বিবেচনা করা উচিত, এটি অন্তর্নির্মিত এবং দ্রুত।

যদি আপনার ইনপুটটি কোনও ভারে থাকে তবে আসুন, $ 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'

4
এই মুহুর্তে কেউ এই উত্তরটিকে অগ্রাহ্য করেনি, সম্ভবত এটি তুলনামূলকভাবে পলকভাবে :)
জোসিপ রডিন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.