Unir argumentos bash en una sola cadena con espacios

40

Estoy tratando de unir todos los argumentos de una función Bash en una sola cadena con espacios que separan cada argumento. También necesito que la cadena incluya comillas simples alrededor de toda la cadena.

Esto es lo que tengo hasta ahora ...

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

Obviamente esto no funciona, pero me pregunto si hay una manera de lograrlo.

Schwagmister
fuente

Respuestas:

57

Creo que esto hace lo que quieres. Pondrá todos los argumentos en una cadena, separados por espacios, con comillas simples alrededor de todos:

str="'$*'"

$*produce todos los argumentos de los scripts separados por el primer carácter de los $IFScuales, por defecto, es un espacio.

Dentro de una cadena con comillas dobles, no hay necesidad de escapar de comillas simples.

Ejemplo

Pongamos lo anterior en un archivo de script:

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

Ahora, ejecute el script con ejemplos de argumentos:

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

Este script es POSIX. Funcionará con bashpero no requiere bash.

Una variación: concatenando con barras en lugar de espacios

Podemos cambiar de espacios a otro personaje ajustando IFS:

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

Por ejemplo:

$ sh script.sh one two three four       
'one/two/three/four'
John1024
fuente
Bien, esto funcionó muy bien e hizo exactamente lo que necesitaba. Estoy tratando de usar esto para cambiar el directorio a un directorio con espacios en el nombre simplemente usando los argumentos. Lo que finalmente necesitaba para esto era crear una función que cambiara los directorios sin tener que escribir los apóstrofos si el directorio tiene palabras espaciadas. Lo que acabo de probar fue lo siguiente: cdm () {str = "'$ *'" cd $ str} Solo accede al primer argumento en str Ejemplo: cdm test 2 Resultado: 'test: No
existe
@Schwagmister: puede guardarlo en una variable (cadena) si lo desea, pero, si no necesita hacerlo específicamente, creo cd "$*"que será lo suficientemente bueno.
Scott
@Schwagmister Las comillas simples no son útiles allí. Proveedores: cdm(){ str="$*"; cd "$str"; }o, como sugiere Scott, cdm(){ cd "$*"; }. Además, tenga en cuenta que $*reemplaza múltiples espacios consecutivos con un solo espacio. Si el nombre de su directorio puede tener múltiples espacios consecutivos o pestañas o nuevas líneas, entonces esos caracteres realmente necesitan escapar antes de pasar a la cdmfunción.
John1024
Entonces, si es algo así como la prueba 2, prueba 1, ¿cómo haría que este comando de CD funcionara correctamente? También esta es una ayuda increíble. Realmente lo aprecio, muchachos. @Scott
Schwagmister
@Schwagmister La mejor manera es poner comillas simples en la línea de comandos cuando se llama cdmcomo en: cdm 'test 2 trial 1'. Esto manejará toda la mansión de nombres extraños. Sin embargo, siempre y cuando los espacios en blanco estén limitados a espacios individuales, cdmentonces se puede ejecutar como cdm test 2 trial 1.
John1024
5

Es más fácil de lo que piensas:

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

echo $array

chmod + x eso y ejecútalo:

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