Unire gli argomenti bash in una singola stringa con spazi


40

Sto cercando di unire tutti gli argomenti a una funzione Bash in un'unica stringa con spazi che separano ogni argomento. Ho anche bisogno che la stringa includa virgolette singole attorno all'intera stringa.

Ecco quello che ho finora ...

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

Ovviamente questo non funziona ma mi chiedo se c'è un modo per raggiungere questo obiettivo?

Risposte:


57

Credo che questo faccia quello che vuoi. Metterà tutti gli argomenti in una stringa, separati da spazi, con virgolette singole intorno a tutti:

str="'$*'"

$*produce tutti gli argomenti degli script separati dal primo carattere di $IFScui, per impostazione predefinita, è uno spazio.

All'interno di una stringa tra virgolette doppie, non è necessario sfuggire alle virgolette singole.

Esempio

Mettiamo quanto sopra in un file di script:

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

Ora esegui lo script con argomenti di esempio:

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

Questo script è POSIX. Funzionerà con bashma non richiede bash.

Una variante: concatenare con barre anziché spazi

Possiamo passare dagli spazi a un altro personaggio regolando IFS:

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

Per esempio:

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

Va bene, ha funzionato alla grande e ha fatto esattamente ciò di cui avevo bisogno. Sto provando a usare questo per cambiare directory in una directory con spazi nel nome semplicemente usando gli argomenti. Ciò che alla fine mi serviva per questo era creare una funzione che cambierà directory senza dover digitare gli apostrofi se la directory ha parole distanziate. Quello che ho appena provato è stato il seguente: cdm () {str = "'$ *'" cd $ str} Accede solo al primo argomento in str Quindi esempio: cdm test 2 Risultato: 'test: nessun file o directory
simile

@Schwagmister: puoi salvarlo in una variabile (stringa) se vuoi, ma, se non hai bisogno di farlo, penso che cd "$*"sarà abbastanza buono.
Scott,

@Schwagmister Le virgolette singole non sono utili lì. Prova: cdm(){ str="$*"; cd "$str"; }o, come suggerisce Scott, cdm(){ cd "$*"; }. Inoltre, tenere presente che $*sostituisce più spazi consecutivi con un singolo spazio. Se il nome della tua directory può avere più spazi consecutivi o tab o newline, allora quei caratteri devono davvero essere salvati prima di essere passati alla cdmfunzione.
Giovanni 1024,

Quindi, se si tratta di qualcosa di simile alla prova 1 di prova 1, come farei a far funzionare correttamente questo comando cd? Anche questo è un aiuto straordinario, lo apprezzo davvero, ragazzi. @ Scott
Schwagmister

@Schwagmister Il modo migliore è quello di mettere le virgolette singole nella riga di comando quando si chiama cdmcome in: cdm 'test 2 trial 1'. Questo gestirà tutto il maniero di nomi strani. Tuttavia, purché gli spazi bianchi siano limitati a spazi singoli, allora cdmpuò essere eseguito come cdm test 2 trial 1.
Giovanni 1024,

5

È più facile di quanto pensi:

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

echo $array

chmod + x quello, ed eseguilo:

$ ./example.sh --foo bar -b az 
--foo bar -b az
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.