Saya mengganti, dari judul umpan, semua karakter kecuali huruf dan digit dengan tanda hubung untuk menggunakan hasilnya sebagai nama file aman untuk sistem file apa pun:
$ t="Episodie 06: No hope of riding home (NEW) - Advanced grammar"
$ echo ${t//[^A-Za-z0-9]/-}
Episodie-06--No-hope-of-riding-home--NEW----Advanced-grammar
Namun saya ingin menyingkat semua strip berulang dengan satu seperti Episodie-06-No-hope-of-riding-home-NEW-Advanced-grammar
Saya menemukan saya dapat mencapainya dengan menggunakan dua pass substitusi:
$ t="Episodie 06: No hope of riding home (NEW) - Advanced grammar"
$ tmp=${t//[^A-Za-z0-9]/-}
$ echo ${tmp//--/-}
Episodie-06-No-hope-of-riding-home-NEW--Advanced-grammar
Saya pikir saya bisa melakukannya dalam sekali jalan seperti:
$ echo ${t//[^A-Za-z0-9]+/-}
tetapi tidak berhasil.
Ada petunjuk?
Catatan: Saya tidak ingin menggunakan sed
alat lain
shopt
dan cangkang mana yang mendukungnya.shopt
khusus untuk bash. Sintaks pola yang diaktifkan selalu tersedia di semua varian ksh. Di zsh, sintaks ini harus diaktifkan dengansetopt ksh_glob
. POSIX tidak memiliki fitur seperti itu, wildcard-nya kurang kuat daripada regexps. Kerang selain bash / ksh / zsh, yang dalam praktiknya sebagian besar berarti abu saat ini, cenderung menempel pada wildcard POSIX.echo "$t" | sed -r 's/[^[:alnum:]]+/-/g; s/^-|-$//'
. Saya menerima jawaban Anda karena persis melakukan apa yang ditanyakan.${var/PATTERN/REPLACEMENT}
konstruksinya juga spesifik untuk ksh / bash / zsh.sed
karena saya tahu lebih baik sintaks dan perilakunya, saya dapat dengan mudah menambahkan pernyataan untuk menghapus garis start / trailing, saya tidak perlu peduli dengan\n
char. Apakahsed
cara yang tersedia lebih sedikit daripadatr
?tr
adalah alat yang baik untuk pekerjaan inisumber
tr
... Namun saya mencoba menyelesaikannya di Bash, kalau tidak saya akan pergi dengansed
:echo "$t" | sed -r 's/[^A-Za-z0-9]+/-/g'
Note: I don't want to go with sed or other tools
Jika Anda ingin tetap menggunakan bash murni, Anda harus puas dengan solusi dua arah. Pergantian string bash menggunakan gumpalan , seperti dalam ekspansi pathname, dan bukan ekspresi reguler. Satu-satunya karakter khusus dalam gumpalan yang
*
,?
dan[]
, yang kasar setara dalam ekspresi reguler.*
,.
dan[]
. Lihatlah wiki Wooledge dan bagian halaman manual dan untuk info lebih lanjut.bash(1)
Parameter Expansion
Pathname Expansion
Sama seperti komentar, ekspansi dua-pass dalam bash murni masih cenderung lebih cepat daripada mencoba melakukan hal yang sama dengan menjalankan program eksternal, jadi saya tidak akan terlalu khawatir tentang hal itu.
sumber
shopt -s extglob; t="${t//+([^A-Za-z0-9])/-}"