Angenommen, ich habe eine Unix-Shell-Variable wie unten
variable=abc,def,ghij
Ich möchte alle Werte (abc
, def
und ghij
) mithilfe einer for-Schleife extrahieren und jeden Wert in eine Prozedur übergeben.
Das Skript sollte das Extrahieren einer beliebigen Anzahl von durch Kommas getrennten Werten aus $variable
ermöglichen.
Sie können das folgende Skript verwenden, um dynamisch durch Ihre Variable zu navigieren, unabhängig davon, wie viele Felder es enthält, solange es nur durch Kommas getrennt ist.
variable=abc,def,ghij
for i in $(echo $variable | sed "s/,/ /g")
do
# call your procedure/other scripts here below
echo "$i"
done
Anstelle des echo "$i"
-Aufrufs oben zwischen der do
und done
in der for-Schleife können Sie Ihre Prozedur proc "$i"
aufrufen.
Update : Das obige Snippet funktioniert, wenn der Wert der Variablen keine Leerzeichen enthält. Wenn Sie eine solche Anforderung haben, verwenden Sie eine der Lösungen, die IFS
ändern kann, und parsen Sie Ihre Variable.
Hoffe das hilft.
Nicht mit IFS herumspielen
Externen Befehl wird nicht aufgerufen
variable=abc,def,ghij
for i in ${variable//,/ }
do
# call your procedure/other scripts here below
echo "$i"
done
Verwenden der Bash-String-Manipulation http://www.tldp.org/LDP/abs/html/string-manipulation.html
Wenn Sie ein anderes Feldtrennzeichen festlegen, können Sie eine for
-Schleife direkt verwenden:
IFS=","
for v in $variable
do
# things with "$v" ...
done
Sie können die Werte auch in einem Array speichern und dann wie in durchlaufen durchlaufen. Wie teile ich einen String in einem Trennzeichen in Bash auf? :
IFS=, read -ra values <<< "$variable"
for v in "${values[@]}"
do
# things with "$v"
done
$ variable="abc,def,ghij"
$ IFS=","
$ for v in $variable
> do
> echo "var is $v"
> done
var is abc
var is def
var is ghij
In dieser Lösung finden Sie einen umfassenderen Ansatz für How, um eine durch Kommas getrennte Liste zu durchlaufen und einen Befehl für jeden Eintrag auszuführen.
Beispiele zum zweiten Ansatz:
$ IFS=, read -ra vals <<< "abc,def,ghij"
$ printf "%s\n" "${vals[@]}"
abc
def
ghij
$ for v in "${vals[@]}"; do echo "$v --"; done
abc --
def --
ghij --
#/bin/bash
TESTSTR="abc,def,ghij"
for i in $(echo $TESTSTR | tr ',' '\n')
do
echo $i
done
Ich bevorzuge die Verwendung von tr anstelle von sed, da sed in einigen Fällen Probleme mit Sonderzeichen wie\r\n hat.
eine andere Lösung besteht darin, IFS auf ein bestimmtes Trennzeichen zu setzen
Eine andere Lösung, die IFS nicht verwendet und die Leerzeichen trotzdem beibehält:
$ var="a bc,def,ghij"
$ while read line; do echo line="$line"; done < <(echo "$var" | tr ',' '\n')
line=a bc
line=def
line=ghij
Probier diese.
#/bin/bash
testpid="abc,def,ghij"
count=`echo $testpid | grep -o ',' | wc -l` # this is not a good way
count=`expr $count + 1`
while [ $count -gt 0 ] ; do
echo $testpid | cut -d ',' -f $i
count=`expr $count - 1 `
done
Hier ist eine alternative tr-basierte Lösung, die kein Echo verwendet, ausgedrückt als Einzeiler.
for v in $(tr ',' '\n' <<< "$var") ; do something_with "$v" ; done
Es fühlt sich sauberer an ohne Echo, aber das ist nur meine persönliche Vorliebe.