dovecot 사용자 데이터베이스에서 사용자 비밀번호를 변경하는 스크립트를 작성하려고 하는데 sed
.
예를 들어 다음 줄을 확인하세요(이것은 dovecot userdb의 일부입니다).
[email protected]:{SHA512-CRYPT}$6$0vthg.LubtSCxRRK$MdTKNQ2Vk8ZW3XQXNXStt9rfr6fNaXqPvZ0o9WJ8mW8y9ozE1pi8dYM8oQzwWa8ESGzEmJO6yT/tgi3ZEqAiE0:::
[email protected]:{SHA512-CRYPT}$6$0vthg.LubtSCxRRK$MdTKNQ2Vk8ZW3XQXNXStt9rfr6fNaXqPvZ0o9WJ8mW8y9ozE1pi8dYM8oQzwWa8ESGzEmJO6yT/tgi3ZEqAiE0:::
사용자에 대해서만 "{SHA512-CRYPT}"로 시작하는 ":" 구분 기호 사이의 문자열을 바꾸는 방법[이메일 보호됨]"사용자에게는 적용되지 않습니다"[이메일 보호됨]"sed를 사용하시나요?
답변1
아마도:
sed 's/\(\(^\|:\)123@example\.com:\)\([^:]\+\)/\1foo/'
값에 이스케이프된 구분 기호가 없다고 가정합니다.
sed 's/\(\(^\|:\)123@example\.com:\)\([^:]\+\)/\1foo/'
| | | | | | | |
| | | | | | | +----- H. End of sub.
| | | | | | +------- G. Sub string
| | | | | +---------- F. Match Group 1.
| | | | +------------ E. End of Group 3.
| | | +------------------ D. Group 3.
| | +----------------------------------- C. User
| +--------------------------------------------- B. Prefix Group 2.
+--------------------------------------------------- A. Substitute
A:
s/
대체 명령.B:
(^|:)
행 또는 구분 기호의 시작 부분에서 시작하는:
그룹 2는 그룹 1의 일부와 일치합니다.C:
매칭 대상 사용자는 매칭 그룹 1에 속해 있습니다.D:
([^:]+)
삭제할 부분까지 모두 가능합니다:
. 그룹 3의 일부입니다. 다음 구분 기호까지의 모든 것입니다. 어쩌면 그래야 할지도\(:\|$\)
모르지만, 그것으로 끝날 것이기 때문에:
충분할 것입니다.E:
\)
그룹 제거를 종료합니다.F:
\1
일치하는 그룹 1을 다시 놓습니다. 사용자+구분자.G:
foo
모든 것이 지하실에 삽입됩니다.H:
/
모두 끝내세요. 선택적으로/g
전역이지만 한 번만 발생한다고 가정합니다.
답변2
여기에서 주소를 바꿀 수 있습니다.
sed '/^[email protected]:{SHA512-CRYPT}/s/{[^:]*/REPLACE/'
여기서 s///
대체 명령은 address 의 함수이므로 /regxp/
행 s///
이 먼저 상위 주소와 일치하지 않는 한 대체가 시도되지 않습니다.
아니면 그냥 s///
:
sed 's/^\([email protected]:\){SHA512-CRYPT}[^:]*/\1REPLACE/'
또는 123이 콜론 바로 뒤에 나오지 않는 경우에만 줄의 시작 부분에 고정합니다.
sed 's/^\(\(.*:\)*[email protected]:\){SHA512-CRYPT}[^:]*/\1REPLACE/'
나는 확실히 복잡한 하위 표현식에 대해 낯설지 않지만, 이 경우에는 그런 것이 불필요합니다. 나는 일반적으로 주소 형식을 얻을 수 있을 때 선호합니다. 읽기 쉽고, 더 효율적이며, 완전히 이식 가능하다고 생각합니다. 하지만 언뜻 보면 제가 처음에는 여기에 내재된 복잡성을 과대평가한 것처럼 보였습니다.
마찬가지로 역참조와 실제 교체를 분리할 수 있습니다. 예를 들면 다음과 같습니다.
sed -e '
/^\([email protected]:\){SHA512-CRYPT}[^:]*/!b
s//\1REPLACE/
#other commands that can be sure to affect only a line matching the 1st address'
위의 예에서 address는 b
일치하지 않는 줄을 스크립트에서 제거하여 일치를 확인하지만, !
줄이 일치 테스트를 통과하면 다음 대체를 위해 변수 비트를 저장하는 이중 임무도 수행합니다. 게다가 모든 후속 명령은 시작 주소와 일치하는 라인에서만 실행될 수 있습니다.\1
s///
물론 중괄호를 사용하여 일치하는 함수 컨텍스트를 지정하는 덜 궁극적인 형식도 있습니다.
sed -e '
/^[email protected]:{SHA512-CRYPT}/{
s/{[^:]*/REPLACE/
#other function commands
};/other match function/{
#still more commands...
}'
답변3
사용 awk
:
awk -F':' '/^[email protected]/ {$2="NEWPASSWORDHERE"}1' OFS=':' infile
[email protected]:NEWPASSWORDHERE:::
[email protected]:{SHA512-CRYPT}$6$0vthg.LubtSCxRRK$MdTKNQ2Vk8ZW3XQXNXStt9rfr6fNaXqPvZ0o9WJ8mW8y9ozE1pi8dYM8oQzwWa8ESGzEmJO6yT/tgi3ZEqAiE0:::
awk
해당 옵션을 사용하여 콜론()을 필드 구분자로-F
설정 하고 행이 시작되면() 열2를 새 값()으로 바꿉니다 .:
^
[email protected]
$2
NEWPASSWODHERE
OFS=':'
출력 필드 구분 기호를 공백(기본값)에서 콜론(:
)으로 변경합니다.마지막으로
1
인쇄는 기본적으로 활성화됩니다.