Pesquisa de padrões Regex para maiúsculas e minúsculas alternadas

1

Como eu canalizaria o ls a grep para ter um caso de caracter alternativo, como saída?

Por exemplo:

Eu tenho arquivos (1) aAbBaBbA, (2) bAbBaA, (3) bbAB, (4) AAaBbAa, (5) BBBaaa e (6) aBaB.

Eu quero encontrar 1,2,6.

Qual comando eu digitaria?

(Editar) : o meu exemplo não foi tão específico como deveria ter sido. Eu queria incluir alternar a partida com menor e maior. (6) deve ser alterado de aBaB para BaBa , mas eu quero manter o original.

    
por No Time 27.01.2015 / 05:07

4 respostas

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

OUTPUT:

aAbBaBbA
bAbBaA
aBaB

Mas veja a resposta de Pierre para a (obviamente) versão melhor disso.

Ainda assim, existe outra maneira:

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

... embora isso corresponda a apenas um único caractere em uma linha. Você pode corrigir isso fazendo .? entre o ^ e $ no final.

    
por 27.01.2015 / 05:46
5

tente

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

EDIT: como apontado corretamente pelo @mikeserv, isso não funcionará para caracteres não-ASCII. E, de fato, acontecem com bastante frequência (por exemplo, arquivos de música com títulos estrangeiros para nome de arquivo). Então, a maneira mais robusta é:

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

A seguir, mantenho apenas [A-Z] para facilitar a leitura.

Além disso, uma advertência: isso corresponderá a um único caractere (superior ou inferior). Pode-se argumentar que "caso alternado" é definido por nenhum caso similar sucessivo em uma seqüência de zero ou mais caracteres ...: -)

Teste:

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

Mas isso não é suficiente. Mais alguns testes:

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
    
por 27.01.2015 / 07:44
3

Digite este comando:

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

Para quebrar isso.

  • ls é o comando principal

  • É canalizado para grep

  • A opção -P ou -E está informando grep para pesquisar usando expressões regulares (regex)

  • Dentro da citação simples ' e os parênteses () o padrão é apresentado.

  • Basicamente, ele corresponde a qualquer letra superior [[:upper:]] e, em seguida, qualquer letra menor [[:lower:]]

  • Ou usando o canal |

  • Em seguida, corresponda a qualquer letra menor [[:lower:]] e corresponda a qualquer letra superior [[:upper:]]

  • O + irá combinar tudo dentro dos parênteses () e executará através da lista dada.

  • $ informa quando o padrão termina

por 27.01.2015 / 05:07
0

A solução é

grep -E '^([a-z][A-Z])+$'
    
por 27.01.2015 / 05:30