아래와 같이 파일에 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"
$var
s가 쉘 변수의 내용으로 확장되는 인용문은 어휘에서 제거되어야 합니다 .
데이터는 코드가 아닌 데이터에 사용되는 채널을 통해 전달되어야 합니다. sed
( 현대적이거나 현대적이지 않은 프로그래밍 언어와는 sh
반대로 awk
) 그러한 채널이 없으므로 유일한 옵션은 이 데이터를 정리하는 것입니다. 그러나 sed
80년대 이후 더 나은 대안이 등장했습니다.
여기에서 다음을 사용할 수 있습니다.
perl -pi -s -e 's/\bsid=\K.*/\U$value/i' -- -value="$CName" -- "$file"
code 매개변수가 어떻게 고정되는지 참고하세요. s/\bsid=\K.*/\U$value/i
데이터(셸 변수의 내용 $CName
)는 값을 전달하기 위한 별도의 코드가 아닌 매개변수로 전달됩니다( $value
perl 변수에 할당하여).
또한 참고하십시오:
-i
(에서 복사됨perl
) Yes 의 비표준 옵션입니다sed
.I
명령의 표시도 마찬가지입니다sed
.- 아니요, 매치는 라인 끝까지 진행되므로 라인당 한 명의 교체만 가능합니다
g
. 공백이 아닌 문자가 여러 개 뒤따라 일치 한 다음 on a line 으로 변경 되면 의미가 있을 수 있습니다 ..*
s/\bsid=\K\S*/\U$value/gi
sid=
sid=foo SID=bar
sid=new-value SID=new-value
perl
(입력을 사용자 로케일로 인코딩된 텍스트로 해석하는 것과 반대sed
) 기본적으로 각 바이트는 문자로 처리되므로 파일에 사용자 로케일에서 유효한 문자를 형성하지 않는 바이트가 포함되어 있어도 여전히 잘 작동합니다. .\U
(ex/vi에서) 다음 내용을 대문자로 변환합니다. 기본적으로 ASCII 문자에서만 작동합니다. 또한 일부 구현에서는 지원되지만sed
전부는 아니며 표준도 아닙니다. 또는 셸이typeset -u CName
ksh/zsh에서 이를 사용하여 값을 대문자로 변환하거나$CName:u
tcsh/zsh,${(U)CName}
zsh 또는${CName^^}
bash에서 사용하도록 할 수 있습니다. 이는 일반적으로 로케일 인코딩의 텍스트를 해석하고 로케일 규칙에 따라 대소문자를 변경합니다. 예를 들어 로캘에 따라i
변경될 수 있으며I
, 로캘이 iso8859-9 또는 UTF-8을 문자 맵으로 사용하는지 여부에 따라 바이트 0xdd 또는 바이트 0xc4 0xb0으로 인코딩될 수 있습니다.İ
İ
- 참고
\b
하세요단어b
경계sid=foo
, 그래서setsid=foo
일치하지 않습니다. 일부 구현에서는 이를 지원하는sed
반면 다른 구현 에서는\<
/\>
(ex/vi에서) 또는[[:<:]]
/를[[:>:]]
대신 사용합니다. \K
K
일치에서 ept의 시작을 지정합니다. 이전 버전의 경우 괄호 로 묶인 부분을 캡처하여 교체할 때 호출할perl
수 있습니다 . 또는 Lookbehind 연산자를 사용 하지만 제 생각에는 너무 복잡해 보입니다.s/(sid=).*/$1\U$value/i
sid=
$1
s/(?<=sid=).*/\U$value/i
-s
with 대신-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 쉘 구조가 아닙니다.