Bash - Manipulasi String Berkelanjutan


11
#!/bin/bash

FILE="$(basename "$1")"
FILE="${FILE/%.jpeg/.jpg}"

Apakah ada cara untuk merekatkan kedua garis ini menjadi satu garis?

Jawaban:


12

FILE=$(basename "${1/%.jpeg/.jpg}") bekerja untukku.

uji:

bash-$ ./test.sh /tmp/foo.jpeg
foo.jpg

isi skrip:

bash-$ cat test.sh 
#!/usr/bin/bash

FILE=$(basename "${1/%.jpeg/.jpg}")

echo "$FILE"

Karena dua baris agak saling dipertukarkan, solusi ini sejauh ini paling rapi ... Jika garis tidak dipertukarkan sedpasti akan diperlukan kurasa.
gsklee

11

Anda tidak dapat membuat sarang ekspansi di bash (atau di ksh, ash, dan shell lain selain dari zsh). Ini hanya batasan kosmetik, karena seperti yang Anda ilustrasikan, Anda dapat menetapkan ekspresi perantara ke variabel sementara. Agak menyebalkan untuk one-liners, tetapi dalam skrip lebih baik dibaca.

Anda bisa menghindari menggunakan utilitas eksternal basenamedan menggunakan konstruksi manipulasi string sebagai gantinya:

FILE="${1##*/}"; FILE="${FILE/%.jpeg/.jpg}"

Di sini, itu terjadi bahwa Anda dapat menulis ulang skrip Anda untuk menempatkan substitusi perintah di luar . Itu bukan fenomena umum, Anda juga tidak mendapatkan apa pun selain perasaan satu garis tertentu.

Zsh, baik atau buruk, membuat Anda melakukan ekspansi sarang:

FILE=${$(basename $1)/%.jpeg/.jpg}    # using basename
FILE=${${1##*/}/%.jpeg/.jpg}          # using string rewriting

Atau Anda dapat menggunakan konstruksi bawaan zsh alih-alih basename:

FILE=${${1:t}/%.jpeg/.jpg}

4

Saya akan pergi untuk:

FILE=$(basename $1 .jpeg).jpg

Parameter kedua untuk nama file adalah sufiks yang akan dihapus dari nama file (lihat man basename)


3

Anda bisa menggunakan satu sedperintah seperti berikut ini:

FILE=$(sed 's/.*\///;s/\.jpeg$/.jpg/' <<<"$1")

2

Dengan menggabungkan sed, ini harus melakukan trik:

FILE="$(basename "$1" | sed s/\.jpeg$/.jpg/)"

(Ini tidak menjawab pertanyaan Anda karena saya tidak bisa; tidak yakin apakah itu mungkin.)


1

Bash ${}constructs bekerja dengan nama variabel , jadi tidak ada cara untuk menyematkan perintah secara langsung. Pendekatan @ sr_ adalah alternatif jika Anda tidak keberatan dengan garpu tambahan.


1

Garis

FILE=$(basename "${1/%.jpeg/.jpg}")

dapat dipersingkat dan dibuat lebih portabel dengan

FILE=$(basename "${1%.jpeg}.jpg")
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.