ssl.cfg
SSL 요청에 대한 구성 파일( )이 있습니다.
oid_section = OIDs
[req]
default_bits = 4096
prompt = no
default_md = sha256
distinguished_name = dn
attributes = v3_req
[OIDs]
OrganizationID = 2.5.4.97 # Don't touch this
[dn]
C = FO
ST = Foobar Monarchy
O = Lorem Ipsum
CN = specific.domain.com
OrganizationID = ABCDE-12345 # Change this
#...
[v3_req]
#...
교체하려고 해요두번째 OrganizationID
value( ABCDE-12345
) 및 새 값 ABCDE-98765
.
문제는 대부분이 OrganizationID
동일해야 하는 두 개의 동일한 이름 사이의 충돌에 대해 객체를 일치시킨다는 것입니다(아래 부분 [OIDs]
은 마크업 태그이고 두 번째 발생은 실제로사용상표).
내가 시도한 것들:
1) 이 답변에서 수정된 코드 (일치 후 줄 바꾸기) 스택 오버플로:
REQ_ID="ABCDE-98765"
sed -i "/CN =/!b;n;c\\OrganizationID = ${REQ_ID}" ssl.cfg
- 이전 줄과 일치합니다.
CN = ...
!b
현재 경기 중단n
다음 줄 스캔c
선택한 줄을 다음 텍스트로 변경합니다(\
새 줄 인쇄,\\
큰따옴표( )로 인해 이스케이프됨)
나는 이 솔루션이 이전 행의 위치에 의존하기 때문에 별로 좋아하지 않습니다. 누군가 수동으로 CN을 다른 회선으로 바꾸면 문제가 발생합니다.
2) 이전 시도에서 얻은 지식을 활용합니다.
REQ_ID="ABCDE-98765"
sed -i "/\\\[dn\\\]/!b;/OrganizationID/c\\OrganizationID = ${REQ_ID}" ssl.cfg
여기서는 다음을 시도했습니다.
- 일치
[dn]
(이중 이스케이프[
및]
) - 현재 경기 중단
- 이 지점부터 시작하여 다음 OrganizationID 항목을 찾습니다.
- 대신 사용
c\...
이것은 작동하지 않을 것입니다. 두 번째 게임이 처음부터 다시 시작될 것 같은 느낌이 듭니다. 두 항목이 모두 일치하면 아무 것도 바뀌지 않는 것 같습니다.
특히 [dn]의 위치에 관계없이 OrgID를 일치시키는 방법을 찾고 있습니다. 해당 값의 문자열은 ABCDE-
변경되지 않을 수 있지만 이에 의존하고 싶지는 않습니다. 객체 식별자2.5.4.97
변하지 않을 것이다.
결론적으로:
- 특정 줄부터 시작하여 파일을 찾아볼 수 있는 방법이 있나요? (
[dn]
태그 사용) - 위의 목표를 달성할 수 있는 다른 방법이 있나요? (
awk
? 다른 sysutils + 파이프?...)
(제목이 혼란스러워서 사과드립니다. 어떻게 표현해야 좋을지 모르겠습니다.)
답변1
$ awk -v org='ABCDE-12345' -v RS= -v ORS='\n\n' '
$1 == "[dn]" {
$0 = "\n" $0
sub(/\nOrganizationID[[:space:]]*=[^\n]*/,"\nOrganizationID = " org)
sub(/^\n/,"")
}
{ print }
' file
oid_section = OIDs
[req]
default_bits = 4096
prompt = no
default_md = sha256
distinguished_name = dn
attributes = v3_req
[OIDs]
OrganizationID = 2.5.4.97 # Don't touch this
[dn]
C = FO
ST = Foobar Monarchy
O = Lorem Ipsum
CN = specific.domain.com
OrganizationID = ABCDE-12345
#...
[v3_req]
#...
RS=<null>
awk를 빈 줄로 구분된 단락 모드로 설정합니다 RS = ""
(https://www.gnu.org/software/gawk/manual/gawk.html#Multiple-Line), ORS='\n\n'
출력이 빈 줄로 구분되어 있는지 확인하고, $0 = "\n" $0
레코드의 각 줄 앞에 개행 문자가 있는지 확인하여 레코드의 첫 번째 줄에서도 sub()
주변 개행 문자의 후속 사용이 성공하도록 한 다음, 추가한 임시 항목을 제거하세요. 첫 번째 줄 줄 바꿈 단계.OrganizationID
sub(/^\n/,"")
답변2
다음 코드는 으로 시작하는 행의 값을 선택한 값 awk
으로 변경 하지만 부분적으로만 변경하고 해당 키가 처음 나타날 때만 변경합니다.OrganizationID
[dn]
awk -F'=' -v OFS='=' '$0=="[dn]"{f=1} (f)&&$1~/^OrganizationID/{$2="Something-New"; f=0} 1' ssl.cfg
교체 항목을 하드코딩하지 않으려면 다음과 같이 가져올 수 있습니다.
req_id="Something-New"
awk -F'=' -v OFS='=' -v repl="$req_id" '$0=="[dn]"{f=1} (f)&&$1~/^OrganizationID/{$2=repl; f=0} 1' ssl.cfg
(그러나 변수의 이스케이프 시퀀스는 에 의해 해석되므로 awk
리터럴 백슬래시가 필요한 경우 특별한 예방 조치를 취해야 합니다.StackOverflow에 대한 답변입니다.더 읽어보시려면).
위의 코드는 다음을 수행합니다.
=
입력(-F'='
)과 출력( )을 필드 구분 기호로 처리 하므로-v OFS='='
내부적으로 행은 "열"로 분할되고=
출력 행은 둘 사이의 필드 항목을 연결하여 어셈블됩니다=
.현재 줄 전체(
$0
)에 섹션 헤더만 포함되어 있으면[dn]
플래그가f
1로 설정되어 올바른 섹션이 발견되었음을 나타냅니다.오른쪽 섹션에 있고 첫 번째 필드(
$1
즉, 첫 번째 필드 앞의 문자열=
)가 로 시작하는 경우OrganizationID
두 번째 필드( 즉, 첫 번째 필드 뒤의 문자열)가 콘텐츠 콘텐츠$2
로 대체됩니다.=
awk
repl
껍데기$req_id
옵션 변수를 통해-v repl="$req_id"
. 또한 플래그를 재설정하여 해당 value 의 다른 항목을 대체하지 않습니다OrganizationID
.1
규칙 블록 외부의 "혼자"는{ ... }
"현재 줄과 이전 규칙에 의해 수정된 모든 내용을 인쇄합니다"를 줄여서 표현한 것입니다. 이 메커니즘의 기본 아이디어는 실제로 어떤 조건이라도 명시할 수 있다는 것입니다.외부 규칙 블록값이true
0이 아니면awk
현재 줄이 인쇄됩니다(예를 들어awk 'FNR==1'
내부 줄 카운터가 해당 줄FNR
과만 같기 때문에 첫 번째 줄만 인쇄됩니다1
).규칙 블록 내에 명시적인
print
/ 명령이 없거나 다음과 같이 평가되는 "전역" 조건이 있는 경우printf
true
awk
아니요현재 줄을 인쇄합니다.
귀하의 예 출력 :
oid_section = OIDs
[req]
default_bits = 4096
prompt = no
default_md = sha256
distinguished_name = dn
attributes = v3_req
[OIDs]
OrganizationID = 2.5.4.97 # Don't touch this
[dn]
C = FO
ST = Foobar Monarchy
O = Lorem Ipsum
CN = specific.domain.com
OrganizationID =Something-New
#...
[v3_req]
이 코드는 파일을 수정하지는 않지만 결과를 콘솔에 출력합니다(그래서 먼저 올바른지 확인할 수 있습니다). 만족스러우면 출력을 새 파일로 리디렉션하고 수동으로 바꿀 수 있습니다. 또는 지원하는 경우 확장 기능(최근 GNU 구현의 경우 )을 awk
사용할 수 있습니다 .-i inplace
awk
awk -F"=" -v OFS="=" '.. etc ..' ssl.cfg > ssl.cfg.new
또는
awk -i inplace -F"=" -v OFS="=" '.. etc ..' ssl.cfg
답변3
방법 1
for i in `sed -n '/OrganizationID/{;=;}' file| sed -n '2p'`; do sed ''$i's/.*/OrganizationID = ABCDE-98765/g' file; done
파이썬
#!/usr/bin/python
import re
j=[]
t=0
h=re.compile(r'OrganizationID.*')
k=open('file','r')
for i in k:
if re.search(h,i):
t=t+1
if (t == 2):
y=re.sub(h,"OrganizationID = ABCDE-98765",i)
print y.strip()
else:
print i.strip()
else:
print i.strip()
산출
oid_section = OIDs
[req]
default_bits = 4096
prompt = no
default_md = sha256
distinguished_name = dn
attributes = v3_req
[OIDs]
OrganizationID = 2.5.4.97 # Don't touch this
[dn]
C = FO
ST = Foobar Monarchy
O = Lorem Ipsum
CN = specific.domain.com
OrganizationID = ABCDE-98765
답변4
이는 Awk를 사용하여 작업을 수행하는 한 가지 방법입니다. REQ_ID를 내장 연관 배열 ENVIRON에서 사용할 수 있는 awk 명령줄 환경에 배치합니다.
$ REQ_ID="ABCDE-98765" \
awk '
BEGIN { a[1] = "OrganizationID = " ENVIRON["REQ_ID"] }
$1 == "[dn]", match($0, /^OrganizationID[[:blank:]]*=/) {
a[0] = $0
$0 = a[RSTART]
}1
' ssl.cfg
sed를 사용하려면 REQ_ID가 s/// 명령의 RHS에 배치될 수 있는지 확인해야 하므로 약간의 작업이 더 필요합니다.
$ REQ_ID="ABCDE-98765"; s="[[:blank:]]"
$ req_id_esc=$(printf '%s\n' "$REQ_ID" | sed -e 's:[\&/]:\\&:g')
$ sed -e "/^[[]dn]/,/^OrganizationID$s*=/s/^\(OrganizationID\)$s*=.*/\1 = ${req_id_esc}/" ssl.cfg
$ REQ_ID="ABCDE-98765" \
perl -pale '
s//$1 = $ENV{REQ_ID}/ if
$F[0] eq "[dn]" ... /^(OrganizationID)\s*=.*/ and
defined $1' ssl.cfg