Erstellen Sie Text, der mehreren Variablenzuweisungen aus einer einzigen Variablen entspricht

Erstellen Sie Text, der mehreren Variablenzuweisungen aus einer einzigen Variablen entspricht

Ich habe eine Variable, die einen Wert wie diesen hat

line=dog,/path1,/path2

Ich möchte aus dem Wert eine Variable erstellen; d. h. es dogsollte die Variable sein und ich möchte die folgende Ausgabe erhalten:

dog=/path1,/path2
dog1=/path1
dog2=/path2

Wenn ich das habe, line=bull,/val1,/val2brauche ich die folgende Ausgabe.

bull=/val1,/val2
bull1=/val1
bull2=/val2

Beachten Sie, dass linenur drei durch Kommas getrennte Werte vorhanden sind.

Antwort1

Ich denke, das ist es, was Sie versuchen:

line='dog,/path1,/path2'
IFS=', ' read -r -a dog <<< "$line"

echo "$dog"
dog
echo "${dog[1]}"
/path1
echo "${dog[2]}"
/path2 

Dies setzt voraus, dass Ihre Shell Bash ist.

Antwort2

Hier ist eine Bash-zentrierte Lösung:

IFS=, read -r -a vars <<<"$line"
printf "%s\n" "${vars[0]}=${vars[1]},${vars[2]}" "${vars[0]}1=${vars[1]}" "${vars[0]}2=${vars[2]}"

Die erste Zeile teilt Ihre $lineVariable anhand der Kommas in Teile auf. Die zweite Zeile, von innen nach außen arbeitend:

  1. gibt den ersten Wert (z. B. 'Hund') aus, das Gleichheitszeichen, dann die zweiten beiden Werte,
  2. gibt den ersten Wert mit dem angehängten 1Gleichheitszeichen aus, dann den zweiten Wert,
  3. gibt den ersten Wert aus, mit dem Suffix 2, Gleichheitszeichen, dann den dritten Wert,
  4. printfdiese drei Zeichenfolgen, durch Zeilenumbrüche getrennt.

Diese Antwort ist, wie Ihre Frage, fest auf drei Werte in codiert $line.

Beispiele für Eingabe und Ausgabe (die führenden $sind die Shell-Eingabeaufforderungen):

$ line=dog,/path1,/path2
$ IFS=, read -r -a vars <<<"$line"
$ printf "%s\n" "${vars[0]}=${vars[1]},${vars[2]}" "${vars[0]}1=${vars[1]}" "${vars[0]}2=${vars[2]}"
dog=/path1,/path2
dog1=/path1
dog2=/path2

Sie können die printf-Ausgabe ganz einfach in eine Datei umleiten.

Antwort3

Wenn Sie verwenden bash, können Sie etwa Folgendes tun (mit zusätzlichen echoAnweisungen, um zu zeigen, was in jeder Phase geschieht):

$ line=dog,/path1,/path2

$ newline=$(printf "%s\n" "$line" | 
            perl -n -e 'BEGIN {$count=1};
                        my ($var,@values) = split /,/;
                        print "$var=" . join(",",@values);
                        foreach (@values) {
                            printf "%s%i=\"%s\" ",$var, $count++, $_
                        }')

$ echo "$newline"
dog=/path1,/path2 dog1=/path1 dog2=/path2

$ declare $newline

$ declare | grep '^dog'
dog=/path1,/path2
dog1=/path1
dog2=/path2

Dabei wird durch Kommas perlgetrennt $line. Das erste Feld wird in gespeichert $var, der Rest in einem Array namens @values. Anschließend wird eine Ausgabe erzeugt, die für die Verwendung mit dem Bash- declareBefehl zum Festlegen von Variablen geeignet ist.

Beachten Sie, dass $newlinedie Zeile nicht in doppelte Anführungszeichen gesetzt ist und auch nicht gesetzt werden sollte declare. Wenn es in doppelte Anführungszeichen gesetzt wird, declarewird nur ein Argument erhalten, statt drei, die durch Leerzeichen getrennt sind.

Ein unangenehmer Nebeneffekt des fehlenden Zitierens ist, dass diedeclare WILLEschlägt fehl, wenn einer der Feldwerte Leerzeichen usw. enthält, z. B. line=dog,/path /with / spaces,/path2. Sie können dies bei Bedarf beheben, indem Sie entsprechende Anführungszeichen aus den printund printfAnweisungen im perlSkript ausgeben. Und/oder indem Sie es $newlineals Bash-Array statt als Zeichenfolge definieren. Dies bleibt dem Leser als Übung überlassen, da ich bereits genug von dem hier verwendeten Prinzip/der hier verwendeten Technik gezeigt habe.

Wenn Sie sie als exportierte Variablen deklarieren möchten, verwenden Sie:

declare -x $newline

help declareWeitere Einzelheiten finden Sie unter.

Übrigens kshkönnen Sie in typesetanstelle von verwenden declare. typesetwird auch von unterstützt, bashgilt jedoch als veraltet (siehe help typesetin bash).


dog[0]=/path1,/path2Und zum Schluss: Sind Sie sicher, dass Sie nicht lieber eine Shell-Array-Variable (z. B. , dog[1]=/path1, und ) anstelle separater Variablen verwenden möchten dog[2]=/path2? Für solche Dinge gibt es sie nämlich.

Antwort4

Sie könnten so etwas tun. Ich definiere die Zeile wie Sie. Als nächstes analysiere ich das erste durch Kommas getrennte Token aus der Zeile (ich gehe hier davon aus, dass dies für einen Variablennamen gültig ist). Dann konstruiere ich zwei neue Variablen basierend auf dem ersten Token und weise sie dem zweiten und dritten durch Kommas getrennten Token aus der Zeile zu.

line="dog,/path1,/path2"
first="$(echo "${line}" | awk -F, '{ print $1 }')"
eval "${first}1=$(echo "${line}" | awk -F, '{ print $2 }')"
eval "${first}2=$(echo "${line}" | awk -F, '{ print $3 }')"

echo "${dog1}"
/path1
echo "${dog2}"
/path2

verwandte Informationen