ある文字が別の文字の前に表示される場合は、その文字のすべてのインスタンスを置き換えます。

ある文字が別の文字の前に表示される場合は、その文字のすべてのインスタンスを置き換えます。

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'

つまり、.行の先頭を除く文字シーケンスを置き換え、その後に.同じシーケンス sum を追加し、_一致する項目がなくなるまでプロセスを繰り返します。

そしてawk

awk -F = -v OFS== '{gsub(/\./, "_", $1); print}'

右側に=シェル関連の文字(\「$&(); '#~<>...`、スペース、タブ、その他のスペース...)が含まれている場合は、引用符を付ける必要があります。

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をsに置き換えます${i//./_}._

例:

$ 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/=.*=/=/'

=これは、前の点の数に関係なく、2回の交換のみを行うため、次のように入力します。

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

=この方法は、入力例に示すように、1行に1文字しかない場合にうまく機能します。 1行に複数の文字がある場合でも(そして行に1つ以上の文字が含まれている場合にのみ)、
常に最初の文字のみを置き換えるより一般的なアプローチは次のとおりです。===

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

関連情報