sed: 파일에서 유사한 변수 2개를 업데이트하지만 대소문자는 유지합니다.

sed: 파일에서 유사한 변수 2개를 업데이트하지만 대소문자는 유지합니다.

아래와 같이 파일에 2개의 변수가 있고 하나의 사용자 입력으로 삽입된 새 값을 할당해야 합니다. read -p "Enter CName Name : " CName

sid=C02SBX
SID=C02SBX

다음 GNU 문을 실행하면 sed:

sed -i "s/sid=.*/sid=$CName/gI" dbca2.rsp

다음과 같이 변수가 업데이트됩니다.

sid=C03SBX
sid=C03SBX

sid질문: 플래그 앞의 두 번째 문자가 =항상 대문자로 유지되도록 하려면 어떻게 해야 합니까? 예를 들어 SID=C03SBX첫 번째 문자 sid는 소문자로 유지됩니다. 그리고 사용자가 소문자를 입력하든 대문자를 입력하든 기호 뒤의 합은 sid( )처럼 항상 대문자로 입력되어야 하나요?SID==C03SBX

답변1

일반적으로 삽입하면 안 됩니다.데이터내부에암호sed쉘, , awk, perl등 인지 여부에 관계없이 언어 해석기에 대한 인수입니다 python.

그렇게 하면 항상 명령 주입 취약점이 발생하게 됩니다.

그래서 sed -e "code $data", sh -c "code $data", eval "code $data", perl -e "code $data"(참고더블$vars가 쉘 변수의 내용으로 확장되는 인용문은 어휘에서 제거되어야 합니다 .

데이터는 코드가 아닌 데이터에 사용되는 채널을 통해 전달되어야 합니다. sed( 현대적이거나 현대적이지 않은 프로그래밍 언어와는 sh반대로 awk) 그러한 채널이 없으므로 유일한 옵션은 이 데이터를 정리하는 것입니다. 그러나 sed80년대 이후 더 나은 대안이 등장했습니다.

여기에서 다음을 사용할 수 있습니다.

perl -pi -s -e 's/\bsid=\K.*/\U$value/i' -- -value="$CName" -- "$file"

code 매개변수가 어떻게 고정되는지 참고하세요. s/\bsid=\K.*/\U$value/i데이터(셸 변수의 내용 $CName)는 값을 전달하기 위한 별도의 코드가 아닌 매개변수로 전달됩니다( $valueperl 변수에 할당하여).

또한 참고하십시오:

  • -i(에서 복사됨 perl) Yes 의 비표준 옵션입니다 sed.
  • I명령의 표시도 마찬가지입니다 sed.
  • 아니요, 매치는 라인 끝까지 진행되므로 라인당 한 명의 교체만 가능합니다 g. 공백이 아닌 문자가 여러 개 뒤따라 일치 한 다음 on a line 으로 변경 되면 의미가 있을 수 있습니다 ..*s/\bsid=\K\S*/\U$value/gisid=sid=foo SID=barsid=new-value SID=new-value
  • perl(입력을 사용자 로케일로 인코딩된 텍스트로 해석하는 것과 반대 sed) 기본적으로 각 바이트는 문자로 처리되므로 파일에 사용자 로케일에서 유효한 문자를 형성하지 않는 바이트가 포함되어 있어도 여전히 잘 작동합니다. .
  • \U(ex/vi에서) 다음 내용을 대문자로 변환합니다. 기본적으로 ASCII 문자에서만 작동합니다. 또한 일부 구현에서는 지원되지만 sed전부는 아니며 표준도 아닙니다. 또는 셸이 typeset -u CNameksh/zsh에서 이를 사용하여 값을 대문자로 변환하거나 $CName:utcsh/zsh, ${(U)CName}zsh 또는 ${CName^^}bash에서 사용하도록 할 수 있습니다. 이는 일반적으로 로케일 인코딩의 텍스트를 해석하고 로케일 규칙에 따라 대소문자를 변경합니다. 예를 들어 로캘에 따라 i변경될 수 있으며 I, 로캘이 iso8859-9 또는 UTF-8을 문자 맵으로 사용하는지 여부에 따라 바이트 0xdd 또는 바이트 0xc4 0xb0으로 인코딩될 수 있습니다.İİ
  • 참고 \b하세요단어 b경계sid=foo, 그래서 setsid=foo일치하지 않습니다. 일부 구현에서는 이를 지원하는 sed반면 다른 구현 에서는 \</ \>(ex/vi에서) 또는 [[:<:]]/를 [[:>:]]대신 사용합니다.
  • \KK일치에서 ept의 시작을 지정합니다. 이전 버전의 경우 괄호 로 묶인 부분을 캡처하여 교체할 때 호출할 perl수 있습니다 . 또는 Lookbehind 연산자를 사용 하지만 제 생각에는 너무 복잡해 보입니다.s/(sid=).*/$1\U$value/isid=$1s/(?<=sid=).*/\U$value/i
  • -swith 대신 -var=value환경 변수를 사용하여 데이터를 전달할 수 있습니다 VALUE=$CName perl -pi -e 's/\bsid=\K.*/\U$ENV{VALUE}/i' -- "$file". 값이 민감하고 출력에 노출되어서는 안 되는 경우에는 ps -Af이것이 더 나은 선택이 될 것입니다 . 다른 값 전달 채널이 백슬래시가 포함된 데이터를 손상시키므로 이 방법도 awk여기서 사용하는 방법 입니다 .ENVIRON["VALUE"]
  • 사용자로부터 임의의 문자열을 읽으려면 구문은 bash( Korn과 같은 다른 쉘 IFS= read -rp 'Prompt: ' var에서는 IFS= read -r 'var?Prompt: ')입니다. 그러나 사용자에게 메시지를 표시하는 것은 동일한 매개변수를 사용하여 스크립트를 자동화하거나 재사용하기가 더 어렵기 때문에 일반적으로 최선의 접근 방식은 아닙니다. 일반적으로 인수가 you-script thenewCN사용 가능한 위치 와 같은 명령줄 인수로 입력을 전달하거나 적절한 표준 명령줄 구문 분석을 위해 $1표준 내장 기능을 사용하는 것이 더 좋습니다 .getopts

답변2

그룹화 \(...\)및 참조 사용( \1첫 번째 그룹, \2두 번째 그룹 등에 대해):

sed -i "s/\(sid=\).*/\1${CName^^}/gI" dbca2.rsp

사용자 입력을 대문자로 변환하려면 쉘을 사용하십시오.${var^^}

답변3

=대소문자를 구분하지 않고 바꾸려는 행을 일치시킬 수 있지만 전체 행이 아닌 로 시작하는 부분만 수정하십시오 .

 sed -e "/^[Ss][Ii][Dd]=/s/=*/=${^^CName}/"

${^^…}대문자로 표시되는 매개변수는 다음과 같습니다 .배쉬 기능는 표준 POSIX 쉘 구조가 아닙니다.

관련 정보