我需要能夠從文件中導出一些變量,以便我可以在 BASH 腳本中使用它。文件內容是這樣的:
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
首先,我嘗試source
按原樣使用它,並收到錯誤訊息:command not found
。我嘗試使用export
,這給了我錯誤訊息:not a valid identifier
。
我想只有當我將變數從 更改my.variable.var1
為時,我才能導出my_variable_var1
。
我可以透過切斷 at 的行=
,然後用 s 替換所有.
s _
,然後將變數加回來來做到這一點。
所以我的問題是,是否可以改變:
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
到
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
使用那些很酷的“單襯”中的任何一個嗎?很想使用它,再加上好的學習。
答案1
和sed
:
sed -e :1 -e 's/^\([^=]*\)\./\1_/;t1'
即替換.
行首以外的字元序列,後面跟著.
相同的序列 和_
,並重複該過程,直到不再匹配。
和awk
:
awk -F = -v OFS== '{gsub(/\./, "_", $1); print}'
現在,如果右側包含=
shell 特有的字元(\
“$&();'#~<>...`、空格、製表符、其他空格...),您可能需要引用它:
sed "s/'/'\\\\''/g;:1"'
s/^\([^=]*\)\./\1_/;t1'"
s/=/='/;s/\$/'/"
或者:
awk -F = -v q="'" -v OFS== '
{gsub(q, q "\\" q q)
gsub(/\./, "_", $1)
$2 = q $2
print $0 q}'
答案2
使用bash
:
while IFS='=' read -r i j; do echo "${i//./_}=$j" ; done
我們使用參數擴展模式將變數名稱中的所有s${i//./_}
替換為 s 。.
_
例子:
$ 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
答案3
這是另一個sed
:
sed 'h;s/\./_/g;G;s/=.*=/=/'
這個只進行兩次替換,無論=
so 前面有多少個點,輸入如下:
my.var.an.other.var.with.many.dots=line.with.many:chars:and_numbers.and.stuff
結果是
my_var_an_other_var_with_many_dots=line.with.many:chars:and_numbers.and.stuff
當每行只有一個=
字元時(如範例輸入所示),此方法可以正常運作。一種更通用的方法,即使每行有多個字符,也
始終僅替換第一個字符=
(並且僅當該行至少包含一個時) :=
=
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 =
或者
sed -e '/=/{h;s/\./_/g;G;s/=.*\n[^=]*=/=/' -e '}'
所以輸入如下:
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
它輸出:
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