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])+$'