gawk의 FS에 "[}" 또는 "[)"를 설정하는 방법은 무엇입니까?

gawk의 FS에 "[}" 또는 "[)"를 설정하는 방법은 무엇입니까?

저는 GNU Awk 5.0.1을 사용하고 있으며 [}or [)FS. 나는 그것을 작동시킬 수 없습니다. 내가 시도한 것은 다음과 같습니다.

root@u2004:~# echo test | awk -F '[}' '{printf}'
awk: fatal: invalid regexp: Unmatched [, [^, [:, [., or [=: /[}/
root@u2004:~# echo test | awk -F '[\}' '{printf}'
awk: warning: escape sequence `\}' treated as plain `}'
awk: fatal: invalid regexp: Unmatched [, [^, [:, [., or [=: /[}/
root@u2004:~# echo test | awk -F '[\\}' '{printf}'
awk: fatal: invalid regexp: Unmatched [, [^, [:, [., or [=: /[\}/
root@u2004:~# echo test | awk -F '[}}' '{printf}'
awk: fatal: invalid regexp: Unmatched [, [^, [:, [., or [=: /[}}/
root@u2004:~# echo test | awk -F "[}" '{printf}'
awk: fatal: invalid regexp: Unmatched [, [^, [:, [., or [=: /[}/
root@u2004:~# echo test | awk -F "[\}" '{printf}'
awk: warning: escape sequence `\}' treated as plain `}'
awk: fatal: invalid regexp: Unmatched [, [^, [:, [., or [=: /[}/
root@u2004:~# echo test | awk -F "[\\}" '{printf}'
awk: warning: escape sequence `\}' treated as plain `}'
awk: fatal: invalid regexp: Unmatched [, [^, [:, [., or [=: /[}/
root@u2004:~# echo test | awk -F "[}}" '{printf}'
awk: fatal: invalid regexp: Unmatched [, [^, [:, [., or [=: /[}}/
root@u2004:~#

어떻게 해야 하나요?

답변1

입력 필드 구분 기호( )로 사용된 다중 문자 문자열은 FS정규식으로 해석되므로 해당 문자열은 유효한 정규식이어야 합니다.

awk -F '\\[}' '{ print }'

특별한 작업을 수행할 필요는 없지만 리터럴 여는 대괄호와 일치하도록 }첫 문자를 이스케이프해야 합니다 . [에서와 같이 단일 백슬래시를 사용하면 \[}대괄호가 이스케이프되고 구분 기호 표현식이 [}유효하지 않은 정규 표현식인 으로 설정되므로 두 개의 백슬래시가 필요합니다. 리터럴과 일치시키기 위해 대괄호 표현식을 사용하는 [[]in 을 대신 사용할 수도 있지만 입력 시간을 절약하지 못하고 읽기 어려울 수 있습니다.\\[[

나는 또한 코드를 자유롭게 수정했습니다. 이 printf문은 형식 문자열을 인수로 사용하고 하나 이상의 표현식을 출력합니다. 형식 문자열을 제공하지 않았기 때문에 오류가 발생합니다.

더 짧은 변형은 1(또는 비어 있지 않고 0이 아닌 문자열)을 사용하는 것입니다. 이는 다음과 같은 역할을 합니다.시험이것은 항상 사실입니다. 실제 테스트에서는 현재 레코드(라인)를 인쇄하는 기본 작업이 실행됩니다.

awk -F '\\[}' '1'

...각 입력 줄을 출력하는 것 외에는 흥미로운 작업은 수행되지 않습니다. 구분 기호 값에 대한 더 유용한 테스트는 다음과 같습니다.

awk -F '\\[}' '{ print $1 }'

...각 입력 레코드의 첫 번째 필드를 인쇄합니다. 예 {]ABC를 들어 입력이 {]ABC[}{]123[}.

답변2

다음과 같은 빌드를 시도해 볼 수 있습니다.

awk -v FS='\\[\}'  ' {printf}' input_file

단지 "이중" 이스케이프가 필요합니다.[

기록을 위해 다음과 같은 구조 변형을 사용할 수 있습니다.

 awk 'BEGIN{ FS="\\[\}"}  ' {printf}' input_file

또는

awk   ' {printf}' FS='\\[\}' input_file

이와 같은 구성도 작업을 수행합니다.

awk -F '[[]}' '{printf}' input_file

선택적 구분 기호의 '목록' [에는 과(와)만 포함되어 있어야 합니다.}

PS Single printfawk. 인쇄할 서식 문자열 및 변수와 같은 일부 매개변수를 추가해야 합니다. 다른 답변에서 언급했듯이 전체 줄을 인쇄하려면 '1'대신 사용하십시오.'{printf}'

답변3

나는 대괄호 표현식이 이러한 awk(!)구분자 문제에 대한 가장 간단한 해결책을 제공하는 경우가 많다는 것을 알았습니다. @cas의 의견에 따르면:

$ echo 'one[}two' | awk -F '[[]}' '{print $2}'
two

대괄호 표현식 구문에 익숙해지는 것은 확실히 가치가 있습니다. 익숙하지 않으면 언뜻 보기에는 그렇게 보이지 않을 수도 있지만, 이중 이스케이프(!)보다 단순성과 실용성이 쓰기 쉽고 읽기 쉬운 경우가 많습니다. 물론 grep 등의 다른 유틸리티에서도 사용할 수 있습니다.

관련 정보