Die einfachste Lösung besteht darin, ein Array aus den Argumenten in Anführungszeichen zu erstellen, das Sie dann nach Belieben durchlaufen oder direkt an einen Befehl übergeben können.
eval "array=($string)"
for arg in "${array[@]}"; do echo "$arg"; done
p.s. Bitte kommentieren Sie, wenn Sie einen einfacheren Weg ohne eval
finden .
Bearbeiten:
Aufbauend auf der Antwort von @Hubbitus haben wir eine vollständig bereinigte und korrekt zitierte Version. Hinweis:Dies ist übertrieben und hinterlässt tatsächlich zusätzliche Backslashes in Abschnitten mit doppelten oder einfachen Anführungszeichen vor den meisten Satzzeichen, ist aber unverwundbar für Angriffe.
declare -a "array=($( echo "$string" | sed 's/[][`[email protected]#$%^&*():;<>.,?/\|{}=+-]/\\&/g' ))"
Ich überlasse es dem interessierten Leser, nach eigenem Ermessen zu modifizieren http://ideone.com/FUTHhj
Als ich die Antwort von David Postill sah, dachte ich „das muss doch eine einfachere Lösung geben“. Nach einigem Experimentieren fand ich die folgenden Werke:-
string='"aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"'
echo $string
eval 'for word in '$string'; do echo $word; done'
Das funktioniert, weil eval
erweitert die Zeile (Entfernen der Anführungszeichen und Erweitern von string
), bevor die resultierende Zeile ausgeführt wird (die die Inline-Antwort ist):
for word in "aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"; do echo $word; done
Eine Alternative, die auf dieselbe Zeile erweitert wird, ist:
eval "for word in $string; do echo \$word; done"
Hier string
wird innerhalb der doppelten Anführungszeichen erweitert, aber die $
muss maskiert werden, damit word
in nicht erweitert, bevor die Zeile ausgeführt wird (in der anderen Form hat die Verwendung von einfachen Anführungszeichen den gleichen Effekt). Die Ergebnisse sind:-
[~/]$ string='"aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"'
[~/]$ echo $string
"aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"
[~/]$ eval 'for word in '$string'; do echo $word; done'
aString that may haveSpaces IN IT
bar
foo
bamboo
bam boo
[~/]$ eval "for word in $string; do echo \$word; done"
aString that may haveSpaces IN IT
bar
foo
bamboo
bam boo
Wie mache ich das?
$ for l in "aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"; do echo $l; done
aString that may haveSpaces IN IT
bar
foo
bamboo
bam boo
Was mache ich, wenn mein String in einem bash
ist variabel?
Der einfache Ansatz, den bash
zu verwenden String-Tokenizer funktioniert nicht, da er bei jedem Leerzeichen aufteilt, nicht nur bei denen außerhalb der Anführungszeichen:
[email protected] /f/test
$ cat ./test.sh
#! /bin/bash
string='"aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"'
for word in $string; do echo "$word"; done
[email protected] /f/test
$ ./test.sh
"aString
that
may
haveSpaces
IN
IT"
bar
foo
"bamboo"
"bam
boo"
Um dies zu umgehen, zeigt das folgende Shell-Skript (splitstring.sh) einen Ansatz:
#! /bin/bash
string=$(cat <<'EOF'
"aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"
EOF
)
echo Source String: "$string"
results=()
result=''
inside=''
for (( i=0 ; i<${#string} ; i++ )) ; do
char=${string:i:1}
if [[ $inside ]] ; then
if [[ $char == \\ ]] ; then
if [[ $inside=='"' && ${string:i+1:1} == '"' ]] ; then
let i++
char=$inside
fi
elif [[ $char == $inside ]] ; then
inside=''
fi
else
if [[ $char == ["'"'"'] ]] ; then
inside=$char
elif [[ $char == ' ' ]] ; then
char=''
results+=("$result")
result=''
fi
fi
result+=$char
done
if [[ $inside ]] ; then
echo Error parsing "$result"
exit 1
fi
echo "Output strings:"
for r in "${results[@]}" ; do
echo "$r" | sed "s/\"//g"
done
Ausgabe:
$ ./splitstring.sh
Source String: "aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"
Output strings:
aString that may haveSpaces IN IT
bar
foo
bamboo
bam boo
Quelle:StackOverflow-Antwort Teilen Sie eine Zeichenfolge nur durch Leerzeichen, die sich außerhalb von Anführungszeichen von Choroba befinden. Das Skript wurde an die Anforderungen der Frage angepasst.