Correspondendo a maiúsculas / minúsculas com sed

4

Posso escrever um padrão em sed que corresponda a padrões como Aa , Bb , Cc , etc. (ex. letra maiúscula, deve corresponder à letra minúscula correspondente) sem enumerar todas as possibilidades?

    
por jknappen 25.01.2017 / 15:16

3 respostas

3

Com perl , você pode fazer:

$ echo 'fooÉébAar' | perl -Mopen=locale -pe 's/([[:upper:]])(??{lc$^N})/<$&>/g'
foo<Éé>b<Aa>r

Isso usa o operador perl especial (??{code}) , no qual você pode especificar dinamicamente o regexp para corresponder. Aqui lc$^N é a versão em minúscula de $^N , o último grupo de captura.

Com o GNU sed , você poderia fazer:

$ echo 'fooÉébAar' | sed -Ee 's/./&\L&/g;s/([[:upper:]](.).)/<<>>/g;s/(.).//g'
foo<Éé>b<Aa>r

A ideia é que primeiro acrescentemos cada caractere na entrada com a versão em minúscula ( X se torna Xx , x se torna xx ), portanto, se vermos Xxx depois disso ( ([[:upper:]](.) : X seguiu um caractere repetido), isso significa que temos um caractere maiúsculo seguido por sua versão em minúscula.

Observe que isso não funcionaria para caracteres em forma decomposta. Por exemplo, para É quando expresso como E seguido por um combinação de acento agudo . Para contornar isso, você pode usar o operador% regexp de cluster perl \X graphem:

$ printf 'E\u0301\u0302\u00e9\u0302 \u00c9e\u301 foo Ee\u301\n' |
   perl -Mopen=locale -MUnicode::Normalize -pe '
     s/((?=[[:upper:]])\X)(?{$c1 = $^N})(\X)(??{
       NFD(lc$c1) eq NFD($^N) ? qr{} : qr{(?!)}})/<$&>/g'
<É̂é̂> <Éé> foo Eé

Acima de usar formulários de normalização canônica ( NFD ) para que os clusters de grafos sejam sempre representados da mesma maneira no nível dos caracteres.

Ele ainda não seria compatível com coisas como Fffi , em que (U + FB03) é um caractere único (ligadura tipográfica), mas provavelmente é o mesmo, de qualquer maneira.

    
por 25.01.2017 / 16:41
1

Se você estiver usando Sed em combinação com Bash ou Zsh , você pode usar apenas um pequeno metaprograma , assim:

Código

>echo "AaBCAABbEE"| sed -E "s/'echo {A..Z}|sed -E 's/\w/&\L&/g;y/ /|/''/%/g"
%BCAA%EE

Isso gerará efetivamente todas as combinações para você, usando a expansão da chave de concha (e aninhada sed ), como ilustrado abaixo:

>echo {A..Z}|sed -E 's/\w/&\L&/g;y/ /|/'        
Aa|Bb|Cc|Dd|Ee|Ff|Gg|Hh|Ii|Jj|Kk|Ll|Mm|Nn|Oo|Pp|Qq|Rr|Ss|Tt|Uu|Vv|Ww|Xx|Yy|Zz

Existem provavelmente algumas formas puras de fazer isto também, por ex. aplicando várias substituições em uma linha e / ou usando um espaço de espera para procurar esses pares um por um.

    
por 25.01.2017 / 16:27
0

Combinando bash e sed (neste exemplo, eu uso sed para corresponder e excluir as letras):

$ word="Hey , This is AaBbCc and also Dd!"

$ search="H";search2=${search,,};sed "s/[$search$search2]//g" <<<"$word"
ey , Tis is AaBbCc and also Dd!

$ search="A";search2=${search,,};sed "s/[$search$search2]//g" <<<"$word"
Hey , This is BbCc nd lso Dd!

$ search="D";search2=${search,,};sed "s/[$search$search2]//g" <<<"$word"
Hey , This is AaBbCc an also !

Você só precisa fornecer a letra de pesquisa em maiúsculas em var "search=".

PS: Se você precisar pesquisar letras minúsculas, elas poderão ser transformadas em maiúsculas com ${search^^}

    
por 25.01.2017 / 17:20