Dapatkan bidang terakhir menggunakan substr

101

Saya mencoba menggunakan awkuntuk mendapatkan nama file yang diberikan path absolut ke file tersebut.
Misalnya, ketika diberi jalur input yang /home/parent/child/filenameingin filename saya dapatkan, saya telah mencoba:

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

yang bekerja dengan sempurna.
Namun, saya melakukan pengkodean keras $5yang akan salah jika masukan saya memiliki struktur berikut:

/home/parent/child1/child2/filename

Jadi solusi umum membutuhkan selalu mengambil bidang terakhir (yang akan menjadi nama file).

Apakah ada cara sederhana untuk melakukan ini dengan fungsi substr awk?

Mari
sumber
2
seperti yang ditunjukkan seseorang menggunakan basenameadalah cara resmi untuk melakukan ini, menggunakan awkuntuk ini tidak baik untuk dianggap enteng. : D
Kashyap

Jawaban:

209

Gunakan fakta yang awkmemisahkan garis dalam bidang berdasarkan pemisah bidang, yang bisa Anda tentukan. Karenanya, menentukan pemisah bidang untuk /Anda dapat mengatakan:

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

sebagaimana NFmengacu pada jumlah bidang dari rekaman saat ini, mencetak $NFberarti mencetak yang terakhir.

Jadi diberi file seperti ini:

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

Ini akan menjadi hasilnya:

$ awk -F"/" '{print $NF}' file
filename
filename
filename
fedorqui 'JADI berhenti merugikan'
sumber
3
Ini bekerja dengan sempurna. Saya tidak berpikir tentang variabel $ NF. Terima kasih atas jawaban Anda yang sederhana dan efektif.
Mari
6
Untuk yang kedua dari belakang, gunakan $(NF-1).
Itachi
1
Sedang menulis skrip untuk bekerja dengan beberapa perintah buruh pelabuhan dan ini berhasil. Terima kasih!
Harlin
31

Dalam hal ini lebih baik digunakan basenamedaripada awk:

 $ basename /home/parent/child1/child2/filename
 filename
piokuc
sumber
4
@ Mari FYI dirname melakukan hal yang sebaliknya dan menghapus file jalurnya.
Chris Seymour
5

Pilihan lainnya adalah menggunakan bash substitusi parameter .

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

Jika Anda terbuka untuk solusi Perl, berikut yang mirip dengan solusi awk fedorqui:

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

-F/ditentukan /karena pemisah bidang
$F[-1]adalah elemen terakhir dalam @Flarik pemisahan otomatis

Chris Koknat
sumber
1
Terima kasih. Ini membantu saya untuk mendapatkan yang terakhir kecuali satu bidang. perl -F "/" -lane 'print $ F [-2]' masukan
riderchap
ini bekerja untuk saya saat menerima dari input yang disalurkan. Benar-benar lupa tentang perl.
Chris
3

Ini harus menjadi komentar untuk jawaban nama dasar tetapi saya belum cukup poin.

Jika Anda tidak menggunakan tanda kutip ganda, basenametidak akan berfungsi dengan jalur di mana ada karakter spasi:

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

oke dengan tanda kutip ""

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

contoh file

$ 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
Pierre-Damien
sumber
3

Saya tahu saya seperti terlambat 3 tahun dalam hal ini tetapi .... Anda harus mempertimbangkan perluasan parameter, ini sudah ada di dalamnya dan lebih cepat.

jika masukan Anda dalam var, katakanlah, $ var1, lakukan saja ${var1##*/}. Lihat ke bawah

$ 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
Adriano_Pinaffo
sumber
2

Seperti terlambat 5 tahun, saya tahu, terima kasih untuk semua proposal, saya biasa melakukan ini dengan cara berikut:

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

Senang melihat ada tata krama yang lebih baik

Nicko Glayre
sumber
-1

Anda juga bisa menggunakan:

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

atau

    sed -n 's/.*\/\([^\/]*\)$/\1/p'
SARATH
sumber
1
Pada titik ini tidak ada yang menyukai jawaban ini, mungkin karena itu sangat mirip :)
Josip Rodin