"POSIX BRE" 또는 "POSIX ERE" 정규식을 사용하여 문자열(줄 또는 단어)을 일치시키는 방법아니요bak
있어요?
끝에 파일 이름이 ls | egrep '<regex>'
없는 모든 파일을 찾는 것을 만들고 싶습니다.bak
file1
예를 들어 , file2_bak
, , 및 3개의 파일이 있는 경우 bak_file3
정규 표현식은 file1
and 에만 일치해야 합니다 bak_file3
( 는 일치하지 않음 file2_bak
).
를 사용하여 수행할 수 있다는 것을 알고 있지만 or 옵션을 사용하지 않고 수행하고 ls | grep -v 'bak$'
싶습니다 . -v
이것은 POSIX 정규식의 이론적/학술적 문제일 뿐이므로 사용하고 싶지 않습니다.grep
egrep
-v
bak
마지막에 파일 이름을 일치시키는 방법은 다음과 같습니다.
$ ls | egrep 'bak$'
file2_bak
$
위의 정규식은 bak$
끝에 문자열이 있는 모든 문자열과 일치합니다. bak
하지만 모든 문자열과 일치하는 정규식을 어떻게 작성합니까?하다아니요가지다 bak
마지막에?
답변1
답변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
문자열 과 일치합니다.$
: 줄 끝과 일치
부정적인 뒤돌아보기를 사용하는 경우에도 마찬가지입니다( PCRE
s 호환 grep
버전의 경우).
ls | grep -P '(?<!bak)$'
-P
PCRE
: s를 사용하여 줄을 일치시킵니다.
정규식 분해:
(?<!bak)
: 앞에 문자열이 없으면 다음bak
패턴 만 일치합니다.$
: 줄 끝과 일치
답변4
Perl 확장이 있는 경우 부정 예측을 사용할 수 있습니다.
grep -P '^.{0,2}$|^.*(?!bak)...$'
bak로 끝나지 않는 줄을 일치시키는 데 사용됩니다.