디렉토리의 파일 세트에서 동일한 행 세트 제거

디렉토리의 파일 세트에서 동일한 행 세트 제거

구성을 yaml 파일로 내보내는 drupal 웹 사이트가 있습니다. 웹 양식 구성 요소의 경우 추적을 위해 내부 이메일 주소에 참조로 제출하는 약 200개의 웹 양식이 있습니다.

모든 웹 양식에서 이 이메일을 제거하고 싶습니다. 가장 쉬운 방법은 yaml 구성 파일에서 해당 이메일을 삭제한 다음 다시 가져오는 것입니다.

그래서 나의 현재 작업 흐름은 파일 중 하나를 열고, 그 안에 포함된 줄을 찾은 email_webdev:다음, 해당 파일과 다음 42줄을 삭제하고, 파일을 저장하고, 다음 줄을 열고, 헹구고, 약 200개의 파일에 대해 반복하는 것입니다.

나는 나타나는 모든 파일에서 동일한 42줄의 순서가 지정된 세트를 자동으로 제거하는 단일 줄 또는 스크립트를 찾고 있습니다.

기술적 설명

구성 디렉터리에는 동일한 줄 집합을 제거하려는 약 200개의 파일이 있습니다.

$ ls webform.webform.*
webform.webform.incoming_student_housing_applica.yml
webform.webform.info_for_students.yml
webform.webform.info_request_for_viewbook.yml
webform.webform.inquire_about_a_project.yml

각 Webform 구성 yaml은 들여쓰기된 수백 줄의 구성 데이터이며 기본 형식을 갖습니다. 다음은 행 번호 앞에 발췌한 예입니다.

....
170   test:
171     roles: {  }
172     users: {  }
173     permissions: {  }
174   configuration:
175     roles: {  }
176     users: {  }
177     permissions: {  }
178 handlers:
179   email_webdev:
180     id: email
181     label: 'Webdev Email'
182     handler_id: webdev_email
183     status: true
184     conditions: {  }
185     weight: 0
186     settings:
... 
214       parameters: {  }
215 variants: {  }
216 uuid: 6073470f-bb3b-40ad-8440-a7cb5f3be4d2

위 발췌문의 179-214행에 있는 42행 섹션은 해당 디렉토리에 있는 200개 이상의 파일에서 제거하고 싶은 부분입니다. 그래서 제가 수동으로 한 일은 vim에서 179-214행을 삭제한 다음 저장하는 것이었습니다. 결과는 다음과 같습니다.

...
170   test:
171     roles: {  }
172     users: {  }
173     permissions: {  }
174   configuration:
175     roles: {  }
176     users: {  }
177     permissions: {  }
178 handlers:
179 variants: {  }
180 uuid: 6073470f-bb3b-40ad-8440-a7cb5f3be4d2

길이는 42줄입니다. 42줄은 파일 간에 동일하고 순서도 동일하지만 섹션은 파일의 서로 다른 위치에서 시작됩니다. 예를 들어, 한 파일에서는 1068행에서 시작하고 다른 파일에서는 872행에서 시작할 수 있습니다.

$ grep -n email_webdev *
webform.webform.404.yml:183:  email_webdev:
webform.webform.accommodations_letter_request_fo.yml:219:  email_webdev:
webform.webform.agency_survey.yml:219:  email_webdev:
...

내가 알아낼 수 있는 것은 grep 스위치를 사용하여 -A패턴 일치 후의 줄을 찾는 것뿐입니다.

$ grep -A42  email_webdev *
webform.webform.volunteer_sign_up.yml:  email_webdev:
webform.webform.volunteer_sign_up.yml-    id: email
webform.webform.volunteer_sign_up.yml-    label: 'Webdev Email'
webform.webform.volunteer_sign_up.yml-    handler_id: webdev_email
webform.webform.volunteer_sign_up.yml-    status: true
webform.webform.volunteer_sign_up.yml-    conditions: {  }
webform.webform.volunteer_sign_up.yml-    weight: 0
webform.webform.volunteer_sign_up.yml-    settings:
...

따라서 다음은 이 파일(및 디렉터리의 모든 파일)에서 제거하려는 줄입니다.하지만, 다른 이메일 응답에 표시되기 때문에 행을 삭제하도록 할 수도 없고 id: email다른 행의 패턴을 일치시킬 수도 없습니다. 예를 들어 weight: 0거의 모든 다른 요소에도 표시됩니다 conditions: { }. 그들은 이 섹션의 줄만 읽을 수 있습니다. 이 섹션은 email_webdev:모든 파일에서 동일하며 다음 42줄로 시작하고 계속됩니다.

이 작업을 수행하는 더 쉬운 방법이 있나요?

답변1

먼저 이것을 시도해보고 생성된 새 파일이 요구 사항을 정확히 충족하는지 mv확인하십시오 . 원본 파일 덮어쓰기를 .out다시 활성화합니다 .mv

for file in webform.webform.*; do
    awk '/^  email_webdev:$/{n=42}{if(!n){print}else{n--}}' "$file" > "$file.out"
    mv -- "$file.out" "$file"
done

awk 스크립트가 줄을 감지합니다정확히이와 같이:

  email_webdev:

즉, email_webdev:줄 끝 문자인 공백 두 개입니다.

라인이 감지되면 n=42해당 라인 인쇄를 중지하고 42라인을 계산한 후에만 인쇄를 다시 시작하도록 설정됩니다.

답변2

ex이 작업을 수행하려면 라인 편집기를 사용할 수 있습니다 .

for f in webform.webform.*; do
  printf '%s\n' /email_webdev:/ .,+41d x | ex -s "$f"
end

피복재:

  • 상대 주소 지정을 볼 때마다 여러 줄 주소 지정 모드를 지원하므로 파일 크기가 매우 크지 않는 한 ed/ 줄 편집기를 사용해야 합니다 .ex
  • printf표준 입력을 읽고 입력 파일에 적용하는 ex편집기 코드를 내보냅니다 .ex
  • 먼저 email_webdev다음을 검색하여 현재 줄을 설정합니다 /email_webdev:/.
  • 그런 다음 현재 줄부터 시작하여 42줄의 블록을 가져옵니다 .,.+41d.
  • 작업이 완료되었으므로 이제 저장하고 종료합니다.x

추신: 179-214 범위는 42줄이 아닙니다.

관련 정보