Jawaban:
basename
dari GNU coreutils dapat membantu Anda melakukan pekerjaan ini:
$ basename /root/video.mp4
video.mp4
Jika Anda sudah tahu ekstensi file, Anda dapat memohon basename
menggunakan sintaks basename NAME [SUFFIX]
untuk menghapusnya:
$ basename /root/video.mp4 .mp4
video
Atau opsi lain akan memotong semuanya setelah titik terakhir menggunakan sed
:
$ basename /root/video.old.mp4 | sed 's/\.[^.]*$//'
video.old
Solusi termudah adalah menghapus semuanya sampai tampilan terakhir /
:
echo /root/video.mp4 | sed 's/.*\///'
Gunakan salah satu dari cara berikut:
out_file="${in_file##*/}"
out_file="$(basename $in_file)"
out_file="$(echo $in_file | sed 's=.*/==')"
out_file="$(echo $in_file | awk -F"/" '{ print $NF }')"
ps. Anda mendapatkan string yang sama karena dalam pernyataan Anda \(.*\.\)
cocok dengan string dari awal hingga titik ( /root/video.
) dan kemudian Anda secara manual menambahkan .mp4
yang sama dengan di string asli Anda. Anda harus menggunakannya s=.*\([^/]*\)=\1=
sebagai gantinya.
Perbarui: (Yang pertama sudah diperbaiki sekarang)
Untuk mendapatkan satu-satunya nama file tanpa ekstensi, Anda dapat:
out_file="$(echo $in_file | sed 's=.*/==;s/\.[^.]*$/.new_ext/')"
out_file="$(echo $in_file | sed 's=\([^/]*\)\.[^./]*$=\1.new_ext=')"
out_file="$(echo $in_file | awk -F"/" '{ gsub (/\.[^/.]*$/,".new_ext",$NF);print $NF }'
my.file.tar.gz
.
sed
dan awk
. Tetap. Terima kasih.
Salah satu dasar penggunaan regex adalah bahwa pola pada dasarnya serakah ketika menetapkan wild card. Sementara jawaban yang diajukan oleh @uloBasEI tentu merupakan jawaban yang berfungsi, itu juga membutuhkan penggunaan perintah nama bas. Pertanyaan asli dari @Shixons meminta solusi hanya menggunakan sed.
Sebelum melanjutkan, selalu membantu untuk mengetahui versi sed yang menjadi target. Saya mengasumsikan BSD (seperti yang dikirim dengan OSX).
Pertama-tama, pola yang diajukan dalam pertanyaan awal tidak berfungsi karena ia menangkap semuanya dari awal string input hingga dan termasuk titik terakhir. Tanpa jangkar, pencarian ini akan menelan semuanya dari kiri ke kanan. Karenanya, pola yang cocok "/ 1" adalah segalanya dan termasuk titik terakhir. Bahkan nama file dengan banyak titik akan ditelan utuh. Bukan hasil yang diinginkan sama sekali.
Langkah pertama adalah membangun strategi untuk mengidentifikasi pola. Di sini, Anda ingin menyingkirkan semuanya di sebelah kiri nama file (kami akan membahas ekstensi nanti):
out_file="$(echo $in_file | sed 's/^\(\/.*\/\)*.*/\1/')"
Pencarian cocok dari awal string. Ini cocok dengan pola "/.*" nol kali atau lebih dan menghapus semuanya sesudahnya. Kami mencetak pola yang cocok dengan "\ 1". Kami tidak mencari secara global; kami mencari dari awal string dengan menentukan ^ anchor.
Kami mendapatkan kejelasan yang lebih baik dengan mengaktifkan opsi "-E" sehingga kami tidak harus keluar dari tanda kurung:
out_file="$(echo $in_file | sed -E 's/^(\/.*\/)*.*/\1/')"
Jadi sekarang kita memiliki bagian di sebelah kiri. Mari kita tambahkan bagian di sebelah kanan. Perhatikan bahwa kita perlu menjaga bagian kiri sebagai pola karena dengan begitu kita dapat menentukan bahwa itu muncul nol atau lebih. Yang kami lakukan sekarang adalah menambahkan pola untuk bagian di sebelah kanan:
out_file="$(echo $in_file | sed -E 's/^(\/.*\/)*(.*)/\2/')"
Kami hanya mencetak pertandingan kedua, dengan demikian membuang semuanya kecuali nama file. Tetapi kita masih perlu menghapus ekstensi nama file.
out_file="$(echo $in_file | sed -E 's/^(\/.*\/)*(.*)\..*$/\2/')"
"$" Di akhir adalah opsional.
Akhirnya, untuk menambahkan ekstensi baru, Anda cukup merevisinya seperti:
out_file="$(echo $in_file | sed -E 's/^(\/.*\/)*(.*)\..*$/\2.mp4/')"
Optimalisasi tambahan adalah membuat garis miring pertama opsional untuk menangani jalur relatif:
out_file="$(echo $in_file | sed -E 's/^([\/]?.*\/)*(.*)\..*$/\2.mp4/')"
Saya menemukan pertanyaan ini dengan menjadi malas sambil mencari pola sed untuk menggantikan nama bas . Saya sedang mengerjakan sistem yang dilucuti yang tidak memiliki perintah yang diinstal.
sed 's/\.[^.]*$//'
seperti yang Anda miliki, akan gagal untuk (tersembunyi).filename
dan.
dan..
direktori