교대 문자에 대한 정규식 패턴 검색

교대 문자에 대한 정규식 패턴 검색

ls교대 로 grep대문자와 소문자를 출력으로 파이프하려면 어떻게 해야 합니까 ?


예를 들어:

파일 (1) aAbBaBbA, (2) bAbBaA, (3) bbAb, (4) AAaBbAa, (5) BBBaaa 및 (6) aBaB가 있습니다.

1,2,6을 찾고 싶습니다.


어떤 명령을 입력해야 하나요?

(편집하다): 내 예가 충분히 구체적이지 않습니다. 아래에서 위로 번갈아 포함하고 싶습니다. (6)부터 시작해야합니다바바도착하다바바, 하지만 원본을 유지하고 싶습니다.

답변1

노력하다

ls -1 | grep -E '^[A-Z]?([a-z][A-Z])*[a-z]?$'

편집: @mikeserv가 올바르게 지적했듯이 이는 ASCII가 아닌 문자에서는 작동하지 않습니다. 실제로 이러한 상황은 매우 자주 발생합니다(예: 파일 이름에 외국 제목이 포함된 음악 파일). 따라서 보다 강력한 접근 방식은 다음과 같습니다.

ls -1 | grep -E '^[[:upper:]]?([[:lower:]][[:upper:]])*[[:lower:]]?$'

아래에서는 가독성을 위해 그대로 두었습니다 [A-Z].

또한 참고할 사항: 이는 단일 문자(대문자 또는 소문자)와 일치합니다. "대체 대소문자"는 연속적인 유사한 대소문자가 없는 0개 이상의 문자 시퀀스로 정의된다고 말할 수 있습니다... :-)

시험:

mkdir -p /tmp/junk
cd /tmp/junk
touch aAbBaBbA bAbBaA bbAb AAaBbAa BBBaaa aBaB

ls -1 | grep -E '^[A-Z]?([a-z][A-Z])*[a-z]?$'
# aAbBaBbA
# aBaB
# bAbBaA

그러나 이것만으로는 충분하지 않습니다. 추가 테스트:

touch aB
touch aBcD
touch aBcDeF
touch aBcDEf
touch Ab
touch AbCd
touch AbCdEf
touch AbCdeF
touch AbCdEF
ls -1 | grep -E '^[A-Z]?([a-z][A-Z])*[a-z]?$'
# aAbBaBbA
# aB
# Ab
# aBaB
# aBcD
# AbCd
# aBcDeF
# AbCdEf
# bAbBaA

답변2

다음 명령을 입력하세요.

ls |grep -E '^([[:upper:]][[:lower:]])+[[:upper:]]?$|^([[:lower:]][[:upper:]])+[[:lower:]]?$'

이것을 분해하려면.

  • ls주요 명령입니다

  • 그것은 파이프로 연결됩니다grep

  • 스위치를 사용 -P하거나 정규식(regex)을 사용하여 검색하라고 -E지시하고 있습니다.grep

  • 패턴은 작은따옴표 '와 괄호 안에 ()배치됩니다 .

  • 기본적으로 대문자 [[:upper:]]와 작은 문자가 일치하도록 읽습니다.[[:lower:]]

  • 또는파이프 사용|

  • 그런 다음 작은 문자와 일치하고 [[:lower:]]대문자와 일치합니다.[[:upper:]]

  • +괄호 안에 있는 모든 항목을 일치 시키고 ()주어진 목록을 통해 재생됩니다.

  • $패턴이 끝나는 시기를 알려줍니다.

답변3

set aAbBaBbA bAbBaA bbAb AAaBbAa BBBaaa aBaB
l= u=;  printf %s\\n    "$@" |
        grep -E "^([${l:=[:lower:]}][${u:=[:upper:]}])+[$l]?$|^([$u][$l])+[$u]?$"

산출:

aAbBaBbA
bAbBaA
aBaB

하지만 피에르의 답변을 참조하세요(확실히)이것의 더 나은 버전.

그러나 다른 방법이 있습니다.

grep -vE '[^[:alpha:]]|[[:lower:]]{2}|[[:upper:]]{2}|^$'

...하지만 이는 한 줄의 단일 문자에만 일치합니다. 그러나 .?사이와 끝 부분을 수행하여 이 문제를 해결할 수 있습니다.^$

답변4

해결책은

grep -E '^([a-z][A-Z])+$'

관련 정보