한 문자가 다른 문자 앞에 나타나면 해당 문자의 모든 인스턴스를 바꿉니다.

한 문자가 다른 문자 앞에 나타나면 해당 문자의 모든 인스턴스를 바꿉니다.

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

=이것은 앞에 점의 개수에 관계없이 두 번의 교체만 수행하므로 다음과 같이 입력하십시오.

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

관련 정보