awk - 빈 레코드 구분 기호: "RS=" 대 "RS='|'" 대 "RS=(|)"

awk - 빈 레코드 구분 기호: "RS=" 대 "RS='|'" 대 "RS=(|)"

RS=레코드 구분 기호를 null/빈 문자열로 설정할 수 있다는 것을 알고 있지만 GNU에서는 awkRS를 정규식으로 정의할 수도 있으므로 이를 사용하기로 결정했으며 RS='|'gawk가 이를 RS="빈 문자열(또는 |)빈 문자열"이지만 이를 리터럴 |문자로 처리하는 반면, RS='X|Y'이렇게 하면 정규식( X또는 Y)으로 올바르게 인식됩니다.

RS='|'awk가 빈 문자열로 처리하지 않을 때 무슨 일이 일어나는지 누군가 설명할 수 있나요 ?

나도 그것을 시도했지만 RS='(|)'완전히 다른 이야기입니다. 전체 입력을 단일 레코드로 취급하는 것으로 보입니다.

답변1

정의에 따르면RS='|' 문자 그대로의 의미 |. 모든 단일 문자 RS는 모든 awk 간의 이식성을 위해 리터럴로 처리됩니다. 그렇지 않으면 스크립트가 RS='|'gawk와 POSIX awk에서 다르게 동작합니다. 따라서 단일 문자 RS는 리터럴이고 RS와 같은 다중 문자 문자열은 정규 표현식입니다. awk 버전이 이를 지원하는 경우 그렇지 않으면 실제로는 문자열의 첫 번째 문자일 뿐입니다(따라서 항상 RS='.'리터럴입니다. .어떤 경우에는 RS='.x'모든 문자 뒤에) xaws 및 기타 텍스트가 옵니다 ..

그런데 단일 문자는 다른 정규식 컨텍스트에서 POSIX에 대해 정의되지 않은 동작이지만 |및와 같은 정규식 반복 문자의 경우와 마찬가지로 많은 도구에서는 이를 리터럴로 처리합니다 |.*?

- "null 또는 null"을 의미 하는 경우 RS='(|)'"null"과 동일하게 로 쓸 수도 있습니다 (). 모든 문자가 일치하는 것 같은데 왜 일치하지 않는지 모르겠습니다. 다양한 도구는 다양한 방식으로 정규식을 인식하는 것 같습니다.

$ printf 'foo\n' | sed -E 's/()/x/g'
xfxoxox
$ printf 'foo\n' | grep -Eo '()'
$
$ printf 'foo\n' | awk '{gsub(/()/,"x")} 1'
xfxoxox
$ printf 'foo\n' | awk -v RS='()' -v ORS='x\n' '1'
foox

나는 GNU Awk 개발자들에게 연락했습니다(참조:https://lists.gnu.org/archive/html/bug-gawk/2021-01/msg00003.html) 그리고 그것으로부터 두 가지를 도출합니다:

  1. 빈 문자열과 일치하는 다중 문자 정규식은 레코드 구분 기호 또는 필드 구분 기호로 사용하면 안 됩니다. 이렇게 하면 RS나 FS가 없는 것으로 처리되어 전체 입력의 단일 레코드(RS의 경우) 또는 전체 레코드의 단일 필드(FS의 경우)로 끝나게 됩니다. 이는 gawk 매뉴얼의 향후 버전에서 명시적으로 언급될 것입니다.
  2. gawk 5.1.0(아마 그 이전 버전도 있었을지 모르겠습니다)에는 위 명령문이 무시될 때 종료 문자가 소비되는 버그가 있습니다. 이제 이에 대한 수정 사항이 작성되었으며 향후 gawk 버전에서 출시될 예정입니다.

관련 정보