Bash-Argumente mit Leerzeichen zu einer einzigen Zeichenfolge zusammenfügen

39

Ich versuche, alle Argumente einer Bash-Funktion in einer einzigen Zeichenfolge mit Leerzeichen zwischen den einzelnen Argumenten zusammenzufügen. Ich muss auch die Zeichenfolge einzelne Anführungszeichen um die gesamte Zeichenfolge enthalten.

Folgendes habe ich bisher ...

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

Das funktioniert natürlich nicht, aber ich frage mich, ob es einen Weg gibt, dies zu erreichen.

Schwagmister
quelle

Antworten:

54

Ich glaube, das macht was du willst. Alle Argumente werden in eine durch Leerzeichen getrennte Zeichenfolge mit einfachen Anführungszeichen gesetzt:

str="'$*'"

$*Erzeugt alle Skriptargumente, die durch das erste Zeichen getrennt sind $IFS, wobei es sich standardmäßig um ein Leerzeichen handelt.

In einer Zeichenfolge mit doppelten Anführungszeichen müssen einfache Anführungszeichen nicht ausgeblendet werden.

Beispiel

Lassen Sie uns das Obige in eine Skriptdatei schreiben:

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

Führen Sie nun das Skript mit Beispielargumenten aus:

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

Dieses Skript ist POSIX. Es wird funktionieren, bashaber es erfordert nicht bash.

Eine Variante: Verketten mit Schrägstrichen statt Leerzeichen

Wir können von Leerzeichen zu einem anderen Zeichen wechseln, indem wir Folgendes anpassen IFS:

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

Beispielsweise:

$ sh script.sh one two three four       
'one/two/three/four'
John1024
quelle
Okay, das hat großartig funktioniert und genau das getan, was ich brauchte. Ich versuche, dieses zu verwenden, um Verzeichnis in ein Verzeichnis mit Leerzeichen im Namen gerade zu ändern, indem ich die Argumente benutze. Was ich letztendlich brauchte, war, eine Funktion zu erstellen, die Verzeichnisse ändert, ohne die Apostrophe eingeben zu müssen, wenn das Verzeichnis Wörter mit Abständen enthält. Was ich gerade ausprobiert habe war folgendes: cdm () {str = "'$ *'" cd $ str} Es greift nur auf das erste Argument in str zu Also Beispiel: cdm test 2 Ergebnis: 'test: Keine solche Datei oder Verzeichnis
Schwagmister
@Schwagmister: Sie können es in einer (Zeichenfolge-) Variablen speichern, wenn Sie möchten, aber wenn Sie das nicht speziell tun müssen, denke ich, cd "$*"wird es gut genug sein.
Scott
@Schwagmister Die einfachen Anführungszeichen sind dort nicht hilfreich. Versuchen Sie : cdm(){ str="$*"; cd "$str"; }oder, wie Scott sagt, cdm(){ cd "$*"; }. Beachten Sie auch, dass $*mehrere aufeinanderfolgende Leerzeichen durch ein einzelnes Leerzeichen ersetzt werden. Wenn Ihr Verzeichnisname möglicherweise mehrere aufeinanderfolgende Leerzeichen oder Tabulatoren oder Zeilenumbrüche enthält, müssen diese Zeichen wirklich maskiert werden, bevor sie an die cdmFunktion übergeben werden.
John1024
Wenn es also so etwas wie Test 2, Test 1 ist, wie würde ich dafür sorgen, dass dieser CD-Befehl richtig funktioniert? Auch das ist eine erstaunliche Hilfe, die ich wirklich schätze, Jungs. @Scott
Schwagmister
@Schwagmister Der beste Weg ist , Apostrophe auf der Kommandozeile eingegeben werden beim Aufruf cdmwie in: cdm 'test 2 trial 1'. Dies wird alle Herrenhäuser mit seltsamen Namen behandeln. Solange die Leerzeichen jedoch auf einzelne Leerzeichen beschränkt sind, kann das cdmdann so ausgeführt werden cdm test 2 trial 1.
John1024
5

Es ist einfacher als Sie denken:

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

echo $array

chmod + x that und starte es:

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