awk 반복{n}이 작동하지 않습니다

awk 반복{n}이 작동하지 않습니다

반복 기호 {n}을 사용하여 이 줄을 인쇄하려고 했지만 작동하지 않습니다. 을 위한. 예를 들어 길이가 4자인 모든 줄을 인쇄하고 싶습니다.

 awk '/^.{4}$/' test_data

위의 코드는 이를 인쇄하지 않습니다. 중복 기호를 사용할 수 있도록 수정하려면 어떻게 해야 합니까? 나는 awk '/^....$/' test_data다음과 같은 대안을 알고 있습니다awk 'length ==3 ' test_data

답변1

~에 따르면GNU Awk 사용자 가이드: 기능 역사, 정규식 범위 연산자에 대한 지원이 버전 3.0에 추가되었지만 처음에는 명시적인 명령줄 옵션이 필요했습니다.

새로운 명령줄 옵션:

  • 새로운 명령줄 옵션:
    • --lint-old 옵션은 awk의 원래 버전 7 Unix 버전에서 사용할 수 없었던 구성에 대해 경고하는 데 사용됩니다(V7/SVR3.1 참조).
    • awk의 BWK -m 옵션입니다. (Brian은 당시 Bell Labs에 있었습니다.) 이 문장은 나중에 그의 awk 및 gawk에서 삭제되었습니다.
    • --re-interval 옵션은 정규식에 간격 표현식을 제공하는 데 사용됩니다(정규식 연산자 참조).
    • --compat에 대한 더 나은 이름으로 --traditional 옵션을 추가했습니다(옵션 참조).

gawk4.0 에서는

간격 표현식이 기본 정규 표현식의 일부가 됩니다.

3.x를 사용하고 있으므로 gawk다음을 사용해야 합니다.

awk --re-interval '/^.{4}$/'

또는

awk --posix '/^.{4}$/'

또는 (@StéphaneChazelas 덕분에) 휴대용 솔루션을 원한다면 다음을 사용하십시오.

POSIXLY_CORRECT=anything awk '/^.{4}$/'

( 다른 구현에서는 오류가 발생할 --posix수 있기 때문입니다 .)--re-intervalawk

답변2

오히려(확장 정규식awk또는 )에서 사용된 대로 egrep처음에는 {x,y}. BRE( grepor 에서 사용 sed) 에서 처음 도입되었지만 해당 \{x,y\}구문은 이전 버전의 이식성을 손상시키지 않습니다.

그러나 해당 구문을 사용하여 ERE에 추가되면 RE가 이전에 다른 것과 일치하기 {x,y}때문에 역방향 이식성이 중단됩니다 .foo{2}

따라서 일부 구현에서는 이를 수행하지 않기로 선택합니다. Solaris에서는 여전히 존중 되지 않는다는 /bin/awk것을 알게 될 것입니다 ( 또는 를 사용해야 함 ). FreeBSD와 동일합니다 (기반/bin/nawk/bin/egrep/usr/xpg4/bin/awk/usr/xpg4/bin/grep -EawknawkawkBrian Kernighan이 관리함( k가운데 awk)).

GNU의 경우awkPOSIXLY_CORRECT=anything awk '/^.{4}$/', 최근(버전 4.0)까지 현금화하려면 으로 호출 해야 했습니다 .mawk아직도 존경하지 않는다.

이 연산자는 단지 구문상의 설탕일 뿐입니다. 예제를 .{3,5}작성하는 것은 항상 가능합니다 ....?.?(물론 이렇게 하면 {3,5}더 읽기 쉽지만 그에 상응하는 경우는 (foo.{5,9}bar){123,456}더 나쁩니다).

답변3

awk이는 GNU(gawk)에서 예상되는 것과 일치합니다.

$ printf 'abcd\nabc\nabcde\n' | gawk '/^.{4}$/'
abcd

그러나 실패했습니다. mawkPOSIX 및 AFAIK에 더 가깝고 awkUbuntu 시스템의 기본값입니다.

$ printf 'abcd\nabc\nabcde\n' | mawk '/^.{4}$/'
$ ## prints nothing

따라서 간단한 해결책은 gawk대신 을 사용하는 것입니다 awk. 이 {n}표기법은 POSIX BRE(기본 정규 표현식) 구문의 일부가 아닙니다. grep이것이 여기서도 실패하는 이유입니다 .

$ printf 'abcd\nabc\nabcde\n' | grep '^.{4}$'
$

그러나 ERE(확장 정규 표현식)의 일부입니다.

$ printf 'abcd\nabc\nabcde\n' | grep -E '^.{4}$'
abcd

mawk어떤 정규식 스타일이나 POSIX가 사용하는지 모르겠지만 awkBRE인 것 같아요.. 그들은 다음을 기반으로 하는 이전 버전의 ERE를 사용합니다.스티븐의 대답. 어쨌든 ERE를 구현하지 않는 버전을 사용하고 있거나 awk입력에 실제로 4자를 포함하는 줄이 없습니다. 예를 들어, 표시되지 않는 공백이나 유니코드 문자로 인해 이런 일이 발생할 수 있습니다.

관련 정보