如果某個字元出現在另一個字元之前,則替換該字元的所有實例

如果某個字元出現在另一個字元之前,則替換該字元的所有實例

我需要能夠從文件中導出一些變量,以便我可以在 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

相關內容