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

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

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

위의 코드는 인쇄하지 않습니다. 반복 기호를 사용할 수 있도록 수정하는 방법은 무엇입니까? 내가 좋아하는 대안을 알고 awk '/^....$/' test_dataawk 'length ==3 ' test_data



답변

GNU Awk 사용자 안내서 : 기능 히스토리 에 따르면 정규 표현식 범위 연산자에 대한 지원이 버전 3.0에서 추가되었지만 처음에는 명시 적 명령 행 옵션이 필요했습니다.

새로운 명령 줄 옵션 :

  • 새로운 명령 줄 옵션 :
    • –lint-old 옵션은 원래 버전 7 Unix 버전 awk에서 사용할 수없는 구문에 대해 경고합니다 (V7 / SVR3.1 참조).
    • BWK awk의 -m 옵션. (브라이언은 당시 여전히 벨 연구소에있었습니다.) 이것은 나중에 그의 awk와 gawk에서 제거되었습니다.
    • –re-interval 옵션은 regexp에서 간격 표현식을 제공합니다 (Regexp 연산자 참조).
    • –traditional 옵션이 –compat의 더 나은 이름으로 추가되었습니다 (옵션 참조).

에서 gawk4.0,

간격 표현식은 기본 정규 표현식의 일부가되었습니다

당신이 사용하고 있기 때문에 gawk3.X를, 당신은 사용해야합니다

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

또는

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

또는 (@ StéphaneChazelas 덕분에) 휴대용 솔루션을 원한다면

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

(이후 --posix또는 --re-interval다른 오류 원인이 awk구현).


답변

ERE ( 또는에 의해 사용되는 확장 정규식 )에는 처음에.가 없었습니다 . BRE ( 또는에 의해 사용됨)에서 처음 소개 되었지만 이전 버전의 이식성을 깨뜨리지 않는 구문으로 제공되었습니다.awkegrep{x,y}grepsed\{x,y\}

그러나 해당 {x,y}구문 으로 ERE에 추가되었을 때 foo{2}RE가 이전과 다른 것과 일치 했기 때문에 이식성이 떨어졌습니다 .

따라서 일부 구현은 그렇게하지 않기로 선택했습니다. 당신은 그것을 찾을 수 있습니다 /bin/awk, /bin/nawk/bin/egrepSolaris에서 여전히 (당신이 사용할 필요를 존중하지 않는다 /usr/xpg4/bin/awk거나 /usr/xpg4/bin/grep -E). 에 대한 동일 awknawkFreeBSD의에 (에 따라 브라이언 커니 핸으로 유지 합니다 ( 에서 )).awkkawk

GNU의awk 경우 비교적 최근 (버전 4.0) POSIXLY_CORRECT=anything awk '/^.{4}$/'까지는이를 존중하기 위해이를 호출해야 했습니다. mawk여전히 그것을 존중하지 않습니다 .

연산자는 구문 설탕 일뿐입니다. 예를 들어 .{3,5}항상 쓸 수 있습니다 ....?.?(물론 {3,5}훨씬 더 읽기 쉽고 그에 상응하는 (foo.{5,9}bar){123,456}것이 훨씬 나쁩니다).


답변

이것은 GNU awk(gawk)에서 예상대로 작동합니다 .

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

그러나 실패 mawk POSIX에 더 가까운 는 awkUbuntu 시스템의 기본값 인 AFAIK입니다.

$ 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

mawkPOSIX awk에서 어떤 정규식 풍미가 사용되는지 모르겠지만 BRE라고 생각합니다.. 그들은 Stéphane의 답변 에 따라 이전 버전의 ERE를 사용합니다 . 어쨌든 awkERE를 구현하지 않는 버전을 사용하고 있거나 입력에 실제로 정확히 4자를 가진 행이없는 경우가 있습니다. 예를 들어, 공백이 없거나 글리프를 유니 코드로 인해 발생할 수 있습니다.


답변