Menggabungkan argumen bash menjadi string tunggal dengan spasi

40

Saya mencoba untuk menggabungkan semua argumen ke fungsi Bash menjadi satu string tunggal dengan spasi yang memisahkan setiap argumen. Saya juga perlu memiliki string termasuk tanda kutip tunggal di seluruh string.

Inilah yang saya miliki sejauh ini ...

$array=("$@")
str="\'"
for arg in "${array[@]}"; do
    let $str=$str+$arg+" "
done
let $str=$str+"\'"

Jelas ini tidak berhasil tetapi saya bertanya-tanya apakah ada cara untuk mencapai ini?

Schwagmister
sumber

Jawaban:

57

Saya percaya ini melakukan apa yang Anda inginkan. Ini akan menempatkan semua argumen dalam satu string, dipisahkan oleh spasi, dengan tanda kutip tunggal di semua:

str="'$*'"

$*menghasilkan semua argumen skrip yang dipisahkan oleh karakter pertama $IFSyang, secara default, adalah spasi.

Di dalam string yang dikutip ganda, tidak perlu keluar dari tanda kutip tunggal.

Contoh

Mari kita letakkan di atas dalam file skrip:

$ cat script.sh 
#!/bin/sh
str="'$*'"
echo "$str"

Sekarang, jalankan skrip dengan argumen contoh:

$ sh script.sh one two three four 5
'one two three four 5'

Script ini POSIX. Ini akan bekerja dengan bashtetapi tidak perlu bash.

Variasi: disatukan dengan garis miring bukan spasi

Kami dapat mengubah dari spasi ke karakter lain dengan menyesuaikan IFS:

$ cat script.sh 
#!/bin/sh
old="$IFS"
IFS='/'
str="'$*'"
echo "$str"
IFS=$old

Sebagai contoh:

$ sh script.sh one two three four       
'one/two/three/four'
John1024
sumber
Oke ini bekerja dengan baik dan melakukan apa yang saya butuhkan. Saya mencoba menggunakan ini untuk mengubah direktori ke direktori dengan spasi di namanya hanya dengan menggunakan argumen. Apa yang saya butuhkan pada akhirnya adalah untuk membuat fungsi yang akan mengubah direktori tanpa harus mengetikkan tanda kutip jika direktori memiliki kata spasi. Apa yang baru saja saya coba adalah sebagai berikut: cdm () {str = "'$ *'" cd $ str} Ini hanya mengakses argumen pertama di str Jadi contoh: cdm test 2 Hasil: 'test: Tidak ada file atau direktori seperti itu
Schwagmister
@ Schwagmister: Anda dapat menyimpannya ke dalam variabel (string) jika Anda mau, tetapi, jika Anda tidak secara khusus perlu melakukan itu, saya pikir cd "$*"akan cukup baik.
Scott
@ Schwagmister Kutipan tunggal tidak membantu di sana. Coba: cdm(){ str="$*"; cd "$str"; }atau, seperti yang disarankan Scott cdm(){ cd "$*"; },. Perlu diketahui juga bahwa $*mengganti beberapa ruang berurutan dengan satu ruang. Jika nama direktori Anda mungkin memiliki beberapa spasi atau tab atau baris baru berurutan, maka karakter-karakter itu benar-benar perlu diloloskan sebelum mereka dilewatkan ke cdmfungsi.
John1024
Jadi jika itu seperti tes 2 percobaan 1, bagaimana saya membuat perintah cd ini berfungsi dengan benar? Juga ini bantuan luar biasa. Aku sangat menghargainya. @Scott
Schwagmister
@Schwagmister Cara terbaik adalah dengan menempatkan tanda kutip tunggal pada baris perintah saat memanggil cdmseperti di: cdm 'test 2 trial 1'. Ini akan menangani semua manor nama aneh. Namun, selama ruang putih terbatas pada ruang tunggal, maka ruang cdmtersebut dapat dijalankan sebagai cdm test 2 trial 1.
John1024
5

Lebih mudah dari yang Anda pikirkan:

#!/bin/bash
array="${@}"

echo $array

chmod + x itu, dan jalankan:

$ ./example.sh --foo bar -b az 
--foo bar -b az
Klaatu von Schlacker
sumber