egrep이 음수 공백을 무시하는 이유는 무엇입니까?

egrep이 음수 공백을 무시하는 이유는 무엇입니까?

grep -E음수 공백을 사용하면 예상대로 작동하지 않는 이유는 무엇입니까? 즉[^\s]+

내 구문을 분석하기 위해 정규식을 작성했습니다..ssh/config

grep -Ei '^host\s+[^*\s]+\s*$' ~/.ssh/config

# cat ~/.ssh/config
Host opengrok-01-Eight
    Hostname opengrok-01.company.com

Host opengrok-02-SIX
    Hostname opengrok-02.company.com

Host opengrok-03-forMe
    Hostname opengrok-03.company.com

Host opengrok-04-ForSam
    Hostname opengrok-04.company.com

Host opengrok-05-Okay
    Hostname opengrok-05.company.com

Host opengrok-05-Okay opengrok-03-forMe
    IdentityFile /path/to/file

Host opengrok-*
    User root

내가 얻는 것은

Host opengrok-01-Eight
Host opengrok-03-forMe
Host opengrok-05-Okay
Host opengrok-05-Okay opengrok-03-forMe

식스와 샘은 어디에 있나요!

[^\s*]+즉 공백이 아니거나 *, 1 이상이 아닌 항목과 일치하는 것이 실제로 \, s, *1 이상이 아닌 항목과 일치한다는 것을 깨닫는 데 시간이 좀 걸렸습니다 !

정규식은 rex101.com(perl 사용)에서 작동하므로 수정은 매우 간단합니다. 즉, -E스위치-P

# grep -Pi '^host\s+[^*\s]+\s*$' ~/.ssh/config
Host opengrok-01-Eight
Host opengrok-02-SIX
Host opengrok-03-forMe
Host opengrok-04-ForSam
Host opengrok-05-Okay

제가 두려웠던 점은 제가 grep -E수년에 걸쳐 많은 스크립트에서 이것을 사용해 왔지만 이전에는 이것을 발견하지 못했다는 것입니다. 어쩌면 운이 좋았을 수도 있지만 내 테스트 케이스가 그 극단적인 경우를 놓쳤을 가능성이 더 큽니다!

질문:

  1. grep -P모든 확장 정규식 과 함께 사용하도록 변경하는 것 외에 grep -E이 경우 정규식을 어떻게 작성 해야 합니까?
  2. 제가 놓쳤 -E거나 사용하면 짜증나는 다른 문제가 있나요 -P?

grep (GNU grep) 3.1
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Mike Haertel and others, see <http://git.sv.gnu.org/cgit/grep.git/tree/AUTHORS>.

Windows 10에서 실행 중, Ubuntu 18.04(bash)를 실행하는 WSL... 하지만 적절한 Linux 설치에서도 동일한 결과를 얻습니다.

답변1

의 보수는 \sis \S, not [^\s]which ( 의 도움으로 -i) 'SIX' 및 'Sam' 에 리터럴이 포함되어 있으므로 결과에서 제외됩니다 s.


grep -i"호스트"로 시작하여 하나 이상의 공백과 줄 끝까지 이어지는 하나 이상의 문자 시퀀스( *단어나 공백이 존재할 수 없음)를 처리하는 방법 :

grep -Ei '^host[[:space:]]+[^*[:space:]]+$' file
Host opengrok-01-Eight
Host opengrok-02-SIX
Host opengrok-03-forMe
Host opengrok-04-ForSam
Host opengrok-05-Okay

답변2

공백 해석은 \sGNU Grep의 확장입니다. 그것은 정의되어 있지 않습니다POSIX.BSD 쿼리예를 들어 \s공백은 인식되지 않습니다. Perl 정규 표현식도 POSIX 확장이지만 BSD와 GNU 모두 이를 제공합니다. 완전히 이식 가능한 표현식의 경우 를 사용해야 합니다 [[:space:]].

GNU Grep 매뉴얼다소 느슨하게 말하면 "대부분의 메타 문자는 대괄호 표현식 내에서 특별한 의미를 잃습니다". 당신은 이것이 \s그 중 하나이며 실제로는 다음과 같이 만들어졌다는 것을 발견했습니다.POSIX(다시 말하지만) 특수 문자 ., *, [및 는 \대괄호 표현식에서 특별한 의미를 잃어야 합니다. 하지만 여전히 휴대용으로 사용할 수 있습니다 [:space:].

그럼 두 가지 질문에 답해드리자면,

grep -E이 사건에 대한 에세이는 어떻게 작성해야 합니까 ?

grep -Ei '^host[[:space:]]+[^*[:space:]]+[[:space:]]*$'

제가 놓쳤 -E거나 사용하면 짜증나는 다른 문제가 있나요 -P?

.*?일반적인 실수는 플래그 없이 탐욕스럽지 않은 Perl을 시도하는 것입니다 -P.

$ echo 'AB 14 34' | grep -Eo '^.*?4'
AB 14 34
$ echo 'AB 14 34' | grep -Po '^.*?4'
AB 14
$ echo 'AB 14 34' | grep -o  '^.*?4'
{nothing}

마지막 문장:BRE와 EREPRE와는 다릅니다. 정규식을 알아보세요!

관련 정보