Joindre des arguments bash en une seule chaîne avec des espaces


41

J'essaie de joindre tous les arguments d'une fonction Bash en une seule chaîne avec des espaces séparant chaque argument. J'ai également besoin que la chaîne inclue des guillemets simples autour de la chaîne entière.

Voici ce que j'ai jusqu'à présent ...

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

Évidemment, cela ne fonctionne pas, mais je me demande s’il existe un moyen d’y parvenir?

Réponses:


58

Je crois que cela fait ce que vous voulez. Il mettra tous les arguments dans une chaîne, séparés par des espaces, avec des guillemets simples tout autour:

str="'$*'"

$*produit tous les arguments de scripts séparés par le premier caractère $IFS, lequel est par défaut un espace.

Dans une chaîne à double guillemets, il n'est pas nécessaire d'échapper aux guillemets simples.

Exemple

Mettons ce qui précède dans un fichier script:

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

Maintenant, lancez le script avec des exemples d’arguments:

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

Ce script est POSIX. Cela fonctionnera avec bashmais cela n’exige pas bash.

Une variante: concaténer avec des barres obliques au lieu d'espaces

Nous pouvons passer d'espaces à un autre personnage en ajustant IFS:

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

Par exemple:

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

Ok, cela a très bien fonctionné et a fait exactement ce dont j'avais besoin. J'essaie de l'utiliser pour changer de répertoire en un répertoire avec des espaces dans le nom en utilisant simplement les arguments. Ce dont j’avais finalement besoin, c’était de créer une fonction qui modifierait les répertoires sans avoir à taper les apostrophes si le répertoire contient des mots espacés. Ce que je viens d’essayer est le suivant: cdm () {str = "'$ *'" cd $ str} Il n’accède qu’au premier argument de str So exemple: cdm test 2 Résultat: 'test: Aucun fichier ou répertoire de ce type
Schwagmister

@ Schwagmister: Vous pouvez l'enregistrer dans une variable (chaîne) si vous le souhaitez, mais si vous n'avez pas besoin de le faire, je pense que cd "$*"cela suffira.
Scott

@Schwagmister Les guillemets simples ne sont pas utiles ici. Essayez: cdm(){ str="$*"; cd "$str"; }ou, comme le suggère Scott cdm(){ cd "$*"; }. Sachez également que $*remplace plusieurs espaces consécutifs par un seul espace. Si le nom de votre répertoire peut comporter plusieurs espaces, tabulations ou nouvelles lignes consécutives, vous devez alors échapper ces caractères avant de les transmettre à la cdmfonction.
John1024

Donc, si c'est quelque chose comme test 2 essai 1, comment pourrais-je faire fonctionner cette commande cd correctement? C'est aussi une aide incroyable, je l'apprécie vraiment les gars. @Scott
Schwagmister le

@Schwagmister La meilleure façon est de mettre les guillemets simples sur la ligne de commande lors de l' appel cdmcomme dans: cdm 'test 2 trial 1'. Cela gérera tous les manoirs de noms étranges. Cependant, tant que les espaces blancs sont limités à des espaces simples, cdmalors il peut être exécuté en tant que cdm test 2 trial 1.
John1024

5

C'est plus facile que vous ne le pensez:

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

echo $array

chmod + x that, et lancez-le:

$ ./example.sh --foo bar -b az 
--foo bar -b az
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.