RS=
레코드 구분 기호를 null/빈 문자열로 설정할 수 있다는 것을 알고 있지만 GNU에서는 awk
RS를 정규식으로 정의할 수도 있으므로 이를 사용하기로 결정했으며 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'
모든 문자 뒤에) x
aws 및 기타 텍스트가 옵니다 .
.
그런데 단일 문자는 다른 정규식 컨텍스트에서 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) 그리고 그것으로부터 두 가지를 도출합니다:
- 빈 문자열과 일치하는 다중 문자 정규식은 레코드 구분 기호 또는 필드 구분 기호로 사용하면 안 됩니다. 이렇게 하면 RS나 FS가 없는 것으로 처리되어 전체 입력의 단일 레코드(RS의 경우) 또는 전체 레코드의 단일 필드(FS의 경우)로 끝나게 됩니다. 이는 gawk 매뉴얼의 향후 버전에서 명시적으로 언급될 것입니다.
- gawk 5.1.0(아마 그 이전 버전도 있었을지 모르겠습니다)에는 위 명령문이 무시될 때 종료 문자가 소비되는 버그가 있습니다. 이제 이에 대한 수정 사항이 작성되었으며 향후 gawk 버전에서 출시될 예정입니다.