it-swarm.dev

الحصول على آخر حقل باستخدام awk substr

لدي شرط بسيط على النحو التالي ،
أتلقى أسماء الملفات مع الدليل المطلق.
على سبيل المثال ، /home/parent/child/filename
متطلباتي هو خفض اسم الملف من هذا.
ما جربته هو:

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

الذي يعمل تماما.
ولكن هنا الترميز الثابت $5 والذي قد يختلف إذا كان الإدخال الخاص بي به البنية كما يلي:

/home/parent/child1/child2/filename

لذلك يجب أن تكون ديناميكية دون الترميز الثابت. هذا هو المنطق:
خذ دائمًا الحقل الأخير الذي سيكون اسم الملف (لذلك عليك التحقق من الخلف).

يمكن لأي شخص مساعدتي مع وظيفة الركيزة awk أو أي وظيفة أخرى؟

76
Mari

استخدم حقيقة أن 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
166
fedorqui

في هذه الحالة ، من الأفضل استخدام basename بدلاً من awk:

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

إذا كنت منفتحًا على حل Perl ، فإليك حل مشابه لحل fedorqui awk:

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

تعيّن -F// فاصل الحقل
$F[-1] هو العنصر الأخير في صفيف الإكمال التلقائي @F

5
Chris Koknat

خيار آخر هو استخدام bashاستبدال المعلمة .

$ foo="/home/parent/child/filename"
$ echo ${foo##*/}
filename
$ foo="/home/parent/child/child2/filename"
$ echo ${foo##*/}
filename
5
devnull

يجب أن يكون تعليق على إجابة basename لكن ليس لدي نقطة كافية.

إذا لم تستخدم علامات الاقتباس المزدوجة ، فلن يعمل 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
Pierre-Damien

أعلم أنني متأخرة 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
3
Adriano_epifas

مثل خمس سنوات متأخرة ، أعلم ، شكراً لجميع المقترحات ، اعتدت أن أفعل ذلك بالطريقة التالية:

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

سعيد أن تلاحظ أن هناك أخلاق أفضل

1
Nicko Glayre