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

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

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. 줄을 잘라낸 다음 모든 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}'

이제 오른쪽에 =셸에 특수 문자( \"$&();'#~<>...`, 공백, 탭, 기타 공백...)가 포함된 경우 이를 인용할 수 있습니다. :

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

관련 정보