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?


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

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

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

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


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

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

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


-1

Anda juga bisa menggunakan:

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

atau

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

1
Pada titik ini tidak ada yang menyukai jawaban ini, mungkin karena itu sangat mirip :)
Josip Rodin
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.