![한 문자가 다른 문자 앞에 나타나면 해당 문자의 모든 인스턴스를 바꿉니다.](https://linux55.com/image/76737/%ED%95%9C%20%EB%AC%B8%EC%9E%90%EA%B0%80%20%EB%8B%A4%EB%A5%B8%20%EB%AC%B8%EC%9E%90%20%EC%95%9E%EC%97%90%20%EB%82%98%ED%83%80%EB%82%98%EB%A9%B4%20%ED%95%B4%EB%8B%B9%20%EB%AC%B8%EC%9E%90%EC%9D%98%20%EB%AA%A8%EB%93%A0%20%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4%EB%A5%BC%20%EB%B0%94%EA%BF%89%EB%8B%88%EB%8B%A4..png)
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