Apa jenis operasi / # / - di “$ {my_array [@] / # / -}”?

17

Jawaban yang diterima untuk Mengubah array menjadi argumen dari perintah? menggunakan perintah Bash berikut:

command "${my_array[@]/#/-}" "$1"

Saya mencoba mencari tahu apa yang dilakukan /#/-bagian itu, tepatnya. Sayangnya, saya tidak tahu harus menyebutnya apa, jadi saya kesulitan menemukan dokumentasi apa pun. Saya telah melihat-lihat bagian halaman manual Bash pada array dan beberapa situs web, tetapi tidak dapat menemukan apa pun.

Justin
sumber

Jawaban:

24

Ini adalah contoh dari penggantian pola dalam ekspansi parameter shell : ${parameter/pattern/replacement}mengembang ${parameter}, menggantikan instance pertama patterndengan replacement. Dalam konteks pola semacam ini, #adalah khusus: itu berlabuh pola ke awal parameter. Hasil akhir dari semua ini adalah untuk memperluas semua nilai dalam my_arrayarray, yang -masing-masing diawali dengan (dengan mengganti pola kosong di awal setiap parameter).

Stephen Kitt
sumber
2

Ya, itu adalah penggantian pola dalam ekspansi parameter shell sebagai:

${parameter/pattern/replacement}

Tetapi jika karakter pertama setelah yang pertama /adalah salah satu /atau #atau %itu memiliki arti khusus all(diulang), startdan end.

dengan:

$ str='one_#two_two_three_one'

Satu /akan menggantikan instance pertama. Contoh pertama dari one:

$ echo "${str/one/x-x}"
x-x_#two_two_three_one

Atau contoh pertama two:

$ echo "${str/two/x-x}"
one_#x-x_two_three_one

Contoh onedi akhir:

$ echo "${str/%one/x-x}"
one_#two_two_three_x-x

Semua pengulangan two:

$ echo "${str//two/x-x}"
one_#x-x_x-x_three_one

Contoh onedi awal:

$ echo "${str/#one/x-x}"
x-x_#two_two_three_one

Sebuah string yang dimulai dengan #(kutip #):

$ echo "${str/\#two/x-x}"
one_x-x_two_three_one

Tetapi jika Anda membiarkan # (tanpa tanda kutip) sendirian, penggantiannya diatur di awal variabel:

$ echo "${str/#/====}"
====one_#two_two_three_one

Selanjutnya, jika parameternya adalah array, penggantian dilakukan pada semua elemen:

$ str=( one two three )
$ echo "${str[@]/#/==}"
==one ==two ==three
Ishak
sumber
Kata-katanya sedikit menyesatkan karena #dan %merupakan bagian dari pola sementara //operator berbeda dari /dan menggunakan pola yang sama. Anda dapat memiliki pattern='#x'; echo "${var/$pattern}"(atau ${var//$pattern}), tetapi pattern=/x; echo "${var/$pattern}"tidak sama dengan echo "${var//x}". Perhatikan itu #dan %dapat digabungkan zsh, tetapi tidak bashjuga ksh.
Stéphane Chazelas