Ich muss in der Lage sein, einige Variablen aus einer Datei zu exportieren, damit ich sie in meinem BASH-Skript verwenden kann. Der Dateiinhalt sieht ungefähr so aus:
my.variable.var1=a-long-ling.with.lot_of_different:characters:and_numbers
my.variable.another.var2=another-long-ling.with.lot_of_different:characters:and_numbers
my.variable.number3=yet_another_long-ling.with.lot_of_different:characters:and_numbers
Zuerst habe ich versucht, die Quelle source
so zu verwenden, wie sie ist, und habe die folgende Fehlermeldung erhalten: command not found
. Ich habe versucht, zu verwenden export
, was zu der folgenden Fehlermeldung führte: not a valid identifier
.
Ich glaube, ich kann nur exportieren, wenn ich meine Variable von my.variable.var1
in ändere my_variable_var1
.
Dies gelingt mir, indem ich die Zeile bei abschneide =
und dann alle .
s durch _
s ersetze und die Variablen anschließend wieder hinzufüge.
Meine Frage ist also, ob es möglich ist, Folgendes zu ändern:
my.variable.var1=a-long-ling.with.lot_of_different:characters:and_numbers
my.variable.another.var2=another-long-ling.with.lot_of_different:characters:and_numbers
my.variable.number3=yet_another_long-ling.with.lot_of_different:characters:and_numbers
Zu
my_variable_var1=a-long-ling.with.lot_of_different:characters:and_numbers
my_variable_another_var2=another-long-ling.with.lot_of_different:characters:and_numbers
my_variable_number3=yet_another_long-ling.with.lot_of_different:characters:and_numbers
einen dieser coolen „Einzeiler“ verwenden? Würde ich gerne verwenden und außerdem viel lernen.
Antwort1
Mit sed
:
sed -e :1 -e 's/^\([^=]*\)\./\1_/;t1'
Das heißt, ersetzen Sie eine andere Zeichenfolge als .
die am Zeilenanfang, gefolgt von , .
durch dieselbe Zeichenfolge und _
, und wiederholen Sie den Vorgang, bis keine Übereinstimmung mehr vorliegt.
Mit awk
:
awk -F = -v OFS== '{gsub(/\./, "_", $1); print}'
Falls die rechte Seite nun =
für die Shell spezielle Zeichen enthält ( \
"$&();'#~<>...`, Leerzeichen, Tabulator, andere Leerzeichen...), können Sie diese in Anführungszeichen setzen:
sed "s/'/'\\\\''/g;:1"'
s/^\([^=]*\)\./\1_/;t1'"
s/=/='/;s/\$/'/"
Oder:
awk -F = -v q="'" -v OFS== '
{gsub(q, q "\\" q q)
gsub(/\./, "_", $1)
$2 = q $2
print $0 q}'
Antwort2
Verwendung von bash
:
while IFS='=' read -r i j; do echo "${i//./_}=$j" ; done
Wir haben das Parametererweiterungsmuster verwendet, ${i//./_}
um alle .
s _
im Variablennamen durch s zu ersetzen.
Beispiel:
$ cat file.txt
my.variable.var1=a-long-ling.with.lot_of_different:characters:and_numbers
my.variable.another.var2=another-long-ling.with.lot_of_different:characters:and_numbers
my.variable.number3=yet_another_long-ling.with.lot_of_different:characters:and_numbers
$ while IFS='=' read -r i j; do echo "${i//./_}=$j" ; done <file.txt
my_variable_var1=a-long-ling.with.lot_of_different:characters:and_numbers
my_variable_another_var2=another-long-ling.with.lot_of_different:characters:and_numbers
my_variable_number3=yet_another_long-ling.with.lot_of_different:characters:and_numbers
Antwort3
Hier ist ein anderes sed
:
sed 'h;s/\./_/g;G;s/=.*=/=/'
Dieses hier macht nur zwei Ersetzungen, unabhängig von der Anzahl der Punkte vor dem =
„soh“, mit einer Eingabe wie:
my.var.an.other.var.with.many.dots=line.with.many:chars:and_numbers.and.stuff
Das Ergebnis ist
my_var_an_other_var_with_many_dots=line.with.many:chars:and_numbers.and.stuff
Dies funktioniert einwandfrei, wenn =
pro Zeile ein Zeichen vorhanden ist (wie in Ihrer Beispieleingabe).
Ein allgemeinerer Ansatz, der immer nur bis zum ersten ersetzt =
(und nur, wenn die Zeile mindestens ein Zeichen enthält =
), selbst wenn mehrere Zeichen pro Zeile vorhanden sind =
:
sed '/=/{ # if line matches =
h # copy pattern space over the hold space
s/\./_/g # replace all . with =
G # append hold space content to pattern space
s/=.*\n[^=]*=/=/ # replace from the first = up to the first = after
}' # the newline character with a single =
oder
sed -e '/=/{h;s/\./_/g;G;s/=.*\n[^=]*=/=/' -e '}'
also mit einer Eingabe wie:
my.var.with.many.dots.but.no.equal.sign.and.stuff
my.var.with.many.dots=line.with.many:chars:numbers_and.stuff
other.var.with.many.dots=and.with.more.than=one.equal.sign=and.stuff
es gibt aus:
my.var.with.many.dots.but.no.equal.sign.and.stuff
my_var_with_many_dots=line.with.many:chars:numbers_and.stuff
other_var_with_many_dots=and.with.more.than=one.equal.sign=and.stuff