일치하는 두 줄 뒤의 일치하는 텍스트 바꾸기

일치하는 두 줄 뒤의 일치하는 텍스트 바꾸기

다음과 같은 섹션이 포함된 YAML 파일이 있습니다.

admin::common::passwords:
  alice:
    password: '$6$oTQhLvN/4VFJPscD$8LYwUMSFi'
  bob:
    password: '$6$JKOtLF0wHeZfIskt$W/M5.ugDS'

셸 변수 $ACCOUNT에 계정 이름(alice, bob 등)이 포함되어 있고 $YAML이 YAML 파일의 파일 이름인 경우 아래와 같이 sed를 사용하여 새 항목을 추가할 수 있습니다. "admin::common::passwords:" 줄 바로 아래에 새 계정이 삽입되므로 해당 계정이 올바른 섹션에 있다는 것을 알 수 있습니다.

  sed -i /'^admin::common::passwords:'/a"\  ${ACCOUNT}:\n    password: '${ENCRYPTED_PASS}'" $YAML

awk를 사용하여 이와 같은 기존 계정을 찾을 수 있습니다. 이번에도 섹션을 찾은 다음 해당 섹션 내의 계정을 찾습니다(awk에서 이 작업을 수행하는 것이 가능할 수도 있지만 awk로는 충분하지 않으므로 이 작업을 수행합니다).

  awk "BEGIN{RS=ORS="\n\n";FS=OFS="\n"}/admin::common::passwords:/" $YAML | grep -A1 "^[ ]*${ACCOUNT}:"

하지만 행을 삭제하려면 내가 생각할 수 있는 최선의 방법은 다음과 같습니다.

sed -i "/^  ${ACCOUNT}:/,+1d" $YAML

이렇게 하면 admin::common::passwords 섹션이든 다른 곳에 있든 파일의 모든 "^alice:" 줄이 제거됩니다.

파일에 admin::common:passwords 섹션이 포함되어 있다는 것 외에는 파일 내용에 대해 어떤 가정도 할 수 없습니다(그렇지 않으면 내 스크립트의 다른 부분에 의해 생성될 것입니다. 해당 비트는 단순한).

그래서 내 질문은: sed 측면에서 이것을 어떻게 개선할 수 있습니까?"^${ACCOUNT}:" 검색admin::common::passwords 섹션에서을 누른 다음 일치하는 줄과 그 아래 줄을 삭제하세요.'?

(물론 sed를 사용할 필요는 없습니다. awk 또는 심지어 Perl이 작업에 더 적합할 수도 있습니다.)

답변1

sed "
  /^admin::common::passwords:$/,/^[^ ].*:$/ {
     /^  $ACCOUNT:$/ {
       N;d
     }
  }" < "$YAML"

즉, 삭제된 섹션을 admin::common...다음 섹션과 일치하는 섹션 에 포함시킵니다 whatever-section:.

사용자 이름에 흔히 사용되는 문자 .도 정규식 연산자이므로 와 john.doe일치 john.doe하지만 johnWdoe예를 들어 .

admin::common::passwords두 개의 연속 섹션이 있고 삭제하려는 계정이 두 번째 섹션에 있는 경우 위 방법이 작동하지 않습니다.

만약에,오시우스가 지적했듯이, 섹션은 동일하거나 더 적은 수의 선행 공백 문자를 사용하여 다음 줄로 실행되며 섹션에 admin::common::passwords:선행 공백이 있을 수 있습니다. 그러면 다른 언어로 전환해야 할 때가 될 수 있습니다 awk. 예를 들면 다음과 같습니다.

awk -v account="$ACCOUNT" '
  match($0, /[^ ]/) && RSTART <= n {n = 0}
  n && NF == 1 && $1 == account ":" {getline; next}
  !n && /^ *admin::common::passwords:$/ {
    match($0, /[^ ]/)
    n = RSTART
  }
  {print}' < "$YAML"

답변2

전체 파일을 구문 분석하기 위해 미리 만들어진 라이브러리를 사용하는 것이 더 안전할 것입니다(예: 다음과 같습니다).https://stackoverflow.com/questions/1773805/how-can-i-parse-a-yaml-file)을 클릭하여 변경한 다음 수정된 파일을 다시 저장하세요. 이와 같이 구조화된 텍스트 파일에 블라인드 텍스트를 수정하면 문제가 발생할 뿐입니다.

관련 정보