Saya memiliki array "opsi" dari sebuah perintah.
my_array=(option1 option2 option3)
Saya ingin memanggil perintah ini dalam skrip bash, menggunakan nilai dari array sebagai opsi. Jadi, command $(some magic here with my_array) "$1"
menjadi:
command -option1 -option2 -option3 "$1"
Bagaimana saya bisa melakukannya? Apa itu mungkin?
-
awal setiap katamy_array
?Jawaban:
Saya lebih suka
bash
cara yang sederhana :Salah satu alasannya adalah spasi. Sebagai contoh jika Anda memiliki:
The
sed
solusi berbasis akan mengubahnya di-option1 -option2 -with -space -option3
(panjang 5), tetapi di atasbash
ekspansi akan mengubahnya menjadi-option1 -option2 with space -option3
(panjang masih 3). Jarang, tetapi terkadang ini penting, misalnya:sumber
somevar=("${my_array[@]/#/-}")
(Perhatikan tanda kurung di sekitar nilai.) Kemudian tentu saja Anda harus tetap menangani sebagai array yang ketika menggunakannya:echo "${somevar[@]}"
. Mengenai fungsi, di sana Anda terlalu dibatasi oleh kemungkinan bahasa. Anda dapat melewatkan sebuah array:somefunc "${my_array[@]/#/-}"
, kemudian di dalam Anda akan memilikinya di$@
:function somefunc() { echo "$@"; }
. Tetapi hal yang sama$@
akan mengandung parameter lain juga, jika ada, dan tidak ada cara lain untuk mengembalikan array yang diubah daripada stdout.@
subscript array? Saya memberikannya tes dengan zsh 5.5.1 dan satu-satunya perbedaan yang saya perhatikan adalah apa zsh hanya mengawali setiap item saat ditulis${my_array[@]/#/-}
, sementara bash melakukannya untuk*
subskrip juga.Saya tidak memproses bahwa itu dalam sebuah array dan berpikir dipisahkan oleh spasi. Solusi ini akan bekerja dengan itu, tetapi mengingat bahwa itu adalah array, ikuti solusi manatwork (
@{my_array[@]/#/-}
).Ini tidak terlalu buruk dengan
sed
dan subkulit. Seberapa mudah regex tergantung pada apa yang dapat Anda jamin tentang opsi. Jika semua opsi adalah satu "kata" (a-zA-Z0-9
hanya), maka batas kata awal yang sederhana (\<
) akan cukup:Jika opsi Anda memiliki karakter lain (kemungkinan besar
-
), Anda akan memerlukan sesuatu yang sedikit lebih rumit:^
cocok dengan awal baris,[ \t]
cocok dengan spasi atau tab,\|
cocok dengan kedua sisi (^
atau[ \t]
),\(
\)
kelompok (untuk\|
) dan menyimpan hasilnya,\<
cocok dengan awal kata.\1
memulai penggantian dengan menjaga pertandingan pertama dari parens (\(\)
), dan-
tentu saja menambahkan tanda hubung yang kita butuhkan.Ini bekerja dengan gnu sed, jika mereka tidak bekerja dengan Anda, beri tahu saya.
Dan jika Anda akan menggunakan hal yang sama beberapa kali, Anda mungkin ingin menghitungnya sekali saja dan menyimpannya:
sumber
gsed
(saya menginstal menggunakanhomebrew
). Hal lain: alih-alihecho $my_array
, saya perlu lakukanecho ${my_array[@]}
untuk mendapatkan semua item darimy_array
:echo $my_array
hanya memberi saya elemen pertama. Tapi terima kasih atas jawaban dan penjelasan regex, khususnya tentang "batas kata", ini sangat berguna. :)[ $(echo x | sed 's/\</y/') == "yx" ] || exit
.sumber