정규식을 사용하여 끝에 특정 문자열 없이 패턴을 일치시키는 방법

정규식을 사용하여 끝에 특정 문자열 없이 패턴을 일치시키는 방법

"POSIX BRE" 또는 "POSIX ERE" 정규식을 사용하여 문자열(줄 또는 단어)을 일치시키는 방법아니요bak있어요?

끝에 파일 이름이 ls | egrep '<regex>'없는 모든 파일을 찾는 것을 만들고 싶습니다.bak

file1예를 들어 , file2_bak, , 및 3개의 파일이 있는 경우 bak_file3정규 표현식은 file1and 에만 일치해야 합니다 bak_file3( 는 일치하지 않음 file2_bak).

를 사용하여 수행할 수 있다는 것을 알고 있지만 or 옵션을 사용하지 않고 수행하고 ls | grep -v 'bak$'싶습니다 . -v이것은 POSIX 정규식의 이론적/학술적 문제일 뿐이므로 사용하고 싶지 않습니다.grepegrep-v

bak마지막에 파일 이름을 일치시키는 방법은 다음과 같습니다.

$ ls | egrep 'bak$'
file2_bak
$ 

위의 정규식은 bak$끝에 문자열이 있는 모든 문자열과 일치합니다. bak하지만 모든 문자열과 일치하는 정규식을 어떻게 작성합니까?하다아니요가지다 bak마지막에?

답변1

당신이 사용하는 경우 ksh( bash또는확장된 와일드카드활성화 zsh되거나ksh 구활성화됨) 파일 글로빙 모드를 사용하여 원하는 것을 얻을 수 있습니다.

ls -d -- !(*bak)

의 경우 grep간단한 솔루션을 얻으려면 부정을 사용하십시오 -v.

ls | grep -v 'bak$'

답변2

일반 언어(예: "RE와 일치할 수 있음")는 보완어 아래에 닫혀 있으므로 가능하지만 실용적인 목적으로는 그다지 유용하지 않습니다. 조건부로 시작합니다.

마지막 문자는 AND입니다 k. 이전 문자는 AND입니다. a이전 문자는 AND입니다.b

(파이썬 방식으로 작성하겠습니다 s[-1]=='k' and s[-2]=='a' and s[-3]=='b') 따라서 실패한 문자열은

not(s[-1]=='k' and s[-2]=='a' and s[-3]=='b')

not(s[-1]=='k') or not (s[-2]=='a' and s[-3]=='b'))

not(s[-1]=='k') or not(s[-2]=='a') or not(s[-3]=='b')

물론 DeMorgan의 규칙을 두 번 적용합니다. 이는 문자열 길이가 2 이하인 경우 특히 그렇습니다. 따라서 대략 다음과 같은 결과를 얻을 수 있습니다.

grep '^$\|^.$\|^..$\|..[^k]$\|.[^a].$\|[^b]..$'

나는 그것이 유형화 가능하지만 유지 관리가 불가능하다고 생각합니다.

(이론적 측면 참고 사항: 일반적으로 정규 표현식을 결정론적 유한 자동 장치(DFA)로 변환하고 최종 상태를 반전시킨 다음 새 DFA를 모두 잘 정의된 정규 표현식으로 다시 변환할 수 있습니다. 다소 지루하고 오류가 발생하기 쉬운 프로세스입니다).

답변3

사용 find:

find . -maxdepth 1 -type f ! -name "*bak"
  • .: 현재 작업 디렉토리에서 검색하도록 어설션합니다.
  • -maxdepth 1: 지정된 디렉터리 아래 한 수준만 검색하도록 지정(즉, 현재 작업 디렉터리만)
  • -type f: 파일만 검색한다고 주장
  • ! -name "*bak": 다음으로 끝나지 않는 파일 이름만 검색한다고 주장합니다.bak

grep ls그러나 출력을 원하는 경우 :

ls | grep -v 'bak$'
  • -v:주어진 정규식과 일치하지 않는 줄만 인쇄합니다.

정규식 분해:

  • bak: bak문자열 과 일치합니다.
  • $: 줄 끝과 일치

부정적인 뒤돌아보기를 사용하는 경우에도 마찬가지입니다( PCREs 호환 grep버전의 경우).

ls | grep -P '(?<!bak)$'
  • -PPCRE: s를 사용하여 줄을 일치시킵니다.

정규식 분해:

  • (?<!bak): 앞에 문자열이 없으면 다음 bak패턴 만 일치합니다.
  • $: 줄 끝과 일치

답변4

Perl 확장이 있는 경우 부정 예측을 사용할 수 있습니다.

grep -P '^.{0,2}$|^.*(?!bak)...$'

bak로 끝나지 않는 줄을 일치시키는 데 사용됩니다.

관련 정보