2016-07-05 27 views
2

Bash's arrays Verwendung, kann ich eine Liste in einer Array-Variablen speichern und über die Elemente iteriert, während Strings in Anführungszeichen zu halten mit Leerzeichen oder Sonderzeichen zusammen:Wie kann ich eine Liste von Strings in Anführungszeichen in einer Variablen in der Bourne-Shell speichern? (Ohne Schlag-Arrays)

LIST=(--foo --bar --baz "test 1 2 3") 
for item in "${LIST[@]}"; do 
    echo "$item" 
done 

Ausgang ist:

--foo 
--bar 
--baz 
test 1 2 3 

Ich habe ein Skript, das diese Funktion verwendet und leider muss es zu portieren Busybox Asche (die Arrays nicht unterstützt). Ich versuche, eine gute Möglichkeit zu finden, eine Liste zu speichern, in der einige Elemente Leerzeichen enthalten können, während die korrekte Anzahl von Elementen der Liste beibehalten wird.

Dies funktioniert nicht, zum Beispiel (spaltet falsch test 1 2 3 in einzelne Artikel):

LIST='--foo --bar --baz "test 1 2 3"' 
for item in $LIST; do 
    echo "$item" 
done 

Ausgang ist:

--foo 
--bar 
--baz 
"test 
1 
2 
3" 

One idea I found on the Busybox mailing list ist set -- zu verwenden, um die Positionsparameter zu ersetzen:

set -- --foo --bar --baz "test 1 2 3" 
for item in "[email protected]"; do 
    echo "$item" 
done 

Ausgabe ist co rrect:

--foo 
--bar 
--baz 
test 1 2 3 

jedoch clobbers diese Konstruktion die Positionsargumentliste ([email protected]), die dieses Skript auch Anwendungen.

Gibt es einen vernünftigen Weg, ich kann meine Kuchen und es essen und simulieren mehrere willkürliche Arrays in non-Bash sh Variante?

Antwort

1

Der Grund, die meisten Schalen liefern Arrays von einer Art ist, weil Sie nicht sicher sie flach mit simulieren Saiten. Wenn Sie den Code, der ein Array benötigt, vom Rest Ihres Skripts trennen können, können Sie ihn in einer Subshell ausführen, damit die Positionsparameter nach dem Beenden der Subshell wiederhergestellt werden können.

(# Nothing in here can rely on the "real" positional 
    # parameters, unless you can fsave them to a fixed set of indiviual 
    # parameters first. 
    first_arg=$1 # etc 
    set -- --foo --bar --baz "test 1 2 3" 
    for item in "[email protected]"; do 
     echo "$item" 
    done 
    # Any other parameters you set or update will likewise revert 
    # to their former values now. 
) 
2

Sie eine Variable mit \n darin erklären kann:

list='--foo\n--bar\n--baz\n"test 1 2 3"' 

# then iterate it using 
echo -e "$list" | while read -r line; do echo "line=[$line]"; done 

Ausgang:

line=[--foo] 
line=[--bar] 
line=[--baz] 
line=["test 1 2 3"]