Converter todo o texto de maiúsculas para minúsculas e vice-versa?
17
Minha pergunta é como posso converter todo o texto de maiúsculas para minúsculas e vice-versa? Isso é mudar os casos de todas as letras. Tem que ser feito com uma sedsubstituição de alguma forma.
$ echo qWeRtY | sed -e 'y/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/'
QwErTy
ou uma maneira mais curta com o GNU sed, trabalhando com qualquer caractere para o qual exista uma conversão em minúsculas <-> maiúsculas no seu código do idioma:
$ echo qWeRtY | sed -E 's/([[:lower:]])|([[:upper:]])/\U\1\L\2/g'
QwErTy
O seu segundo assume um GNU sede um caso alternativo na entrada. Use em sed -re 's/([[:lower:]]?)([[:upper:]]?)/\U\1\L\2/g'vez disso (ainda específico do GNU). O primeiro converte apenas as 26 letras latinas ASCII, enquanto o segundo converte qualquer letra reconhecida como tal pela sua localidade. O trúnico faz sentido em locais ASCII. O perlúnico funciona para letras latinas ASCII.
Stéphane Chazelas
16
POSIXIAMENTE, isso não pode ser feito, sedexceto fornecendo o conjunto completo de letras que você deseja transliterar como o @cuonglm mostrou .
Poderia ser feito com isso tr, e tré para isso (transliterar):
tr '[:lower:][:upper:]' '[:upper:][:lower:]'
No entanto, no Linux, há limitações. Das 3 trimplementações comumente encontradas em sistemas baseados em Linux:
com o GNU tr, que funciona apenas para conjuntos de caracteres de byte único. Por exemplo, em Stéphane Chazelaslocalidades UTF-8, isso fornece em sTéPHANE cHAZELASvez de sTÉPHANE cHAZELAS. Essa é uma limitação conhecida do GNU tr.
com a trpartir da caixa de ferramentas da herança, isso não funciona (você entende stéphane chazelas).
Esse não é o tipo de coisa que o busybox trfará.
No FreeBSD, porém, isso funciona bem. Você esperaria que ele funcionasse bem em sistemas Unix certificados também.
O bashshell possui um operador dedicado para isso:
Então, no mundo dos desktops, apenas o OSX faz isso? Por que não pode funcionar? São apenas as diferentes implementações, pois parece que há um deslocamento constante no valor hexadecimal entre a versão em minúscula do caractere acentuado e sua contraparte em maiúscula?
1
@ illuminÉ, não sei o que você quer dizer com mundo de desktop . AFAICS, o problema está no GNU, a maioria dos Unices possui "desktops". Além do ASCII e alguns conjuntos de caracteres iso8859, não sei que você pode generalizar a coisa de deslocamento hexadecimal, e isso não faria sentido com codificações como UTF-8. Por exemplo, em UTF-8, maiúsculas ⴠ(e2 b4 a0) é Ⴠ(e1 83 80); ambos i(69) e ı(c4 b1) têm I(49) em maiúsculas (exceto nas localidades turcas onde ise torna İ). A razão pela qual ele não funciona com o GNU tré que o GNU trtrabalha com bytes e não com caracteres.
Stéphane Chazelas
Eu meio que quis dizer mainstream, mas não faz muito sentido, obrigado pelo aviso. Eu apenas olhei os caracteres acentuados franceses (e realmente apenas "é") e fiz suposições muito simplistas, esquecendo novamente que se trata de bytes. Mas a herança? Vou ler essa resposta novamente!
1
@ illuminÉ, para herança, é uma questão diferente, parece que suporta apenas apenas uma ocorrência de [:lower:]ou [:upper:](portanto, a primeira é ignorada). Mesmo em francês, œ -> Œestá c5 93 -> c5 92em UTF-8 e bd -> bcem iso8859-15.
Stéphane Chazelas
2
Embora isso tenha as mesmas limitações já mencionadas como a trsolução oferecida por Stéphane Chazelas, é outra maneira de fazê-lo:
Eu despejo stderrpara /dev/nulllá porque ddtambém fornece estatísticas de todas as suas operações no 2descritor de arquivo. Isso pode ser útil dependendo do que você está fazendo, mas não foi para esta demonstração. Todas as outras coisas com as quais você pode fazer ddainda se aplicam, por exemplo:
tr
seria mais adequado do quesed
.Respostas:
Aqui está uma maneira direta de
sed
:ou uma maneira mais curta com o GNU
sed
, trabalhando com qualquer caractere para o qual exista uma conversão em minúsculas <-> maiúsculas no seu código do idioma:se você pode usar outras ferramentas, como:
perl
(limitado a cartas ASCII):perl
(De forma geral):fonte
sed
e um caso alternativo na entrada. Use emsed -re 's/([[:lower:]]?)([[:upper:]]?)/\U\1\L\2/g'
vez disso (ainda específico do GNU). O primeiro converte apenas as 26 letras latinas ASCII, enquanto o segundo converte qualquer letra reconhecida como tal pela sua localidade. Otr
único faz sentido em locais ASCII. Operl
único funciona para letras latinas ASCII.POSIXIAMENTE, isso não pode ser feito,
sed
exceto fornecendo o conjunto completo de letras que você deseja transliterar como o @cuonglm mostrou .Poderia ser feito com isso
tr
, etr
é para isso (transliterar):No entanto, no Linux, há limitações. Das 3
tr
implementações comumente encontradas em sistemas baseados em Linux:tr
, que funciona apenas para conjuntos de caracteres de byte único. Por exemplo, emStéphane Chazelas
localidades UTF-8, isso fornece emsTéPHANE cHAZELAS
vez desTÉPHANE cHAZELAS
. Essa é uma limitação conhecida do GNUtr
.tr
partir da caixa de ferramentas da herança, isso não funciona (você entendestéphane chazelas
).tr
fará.No FreeBSD, porém, isso funciona bem. Você esperaria que ele funcionasse bem em sistemas Unix certificados também.
O
bash
shell possui um operador dedicado para isso:Com
zsh -o extendedglob
:fonte
ⴠ
(e2 b4 a0) éჀ
(e1 83 80); ambosi
(69) eı
(c4 b1) têmI
(49) em maiúsculas (exceto nas localidades turcas ondei
se tornaİ
). A razão pela qual ele não funciona com o GNUtr
é que o GNUtr
trabalha com bytes e não com caracteres.[:lower:]
ou[:upper:]
(portanto, a primeira é ignorada). Mesmo em francês,œ -> Œ
estác5 93 -> c5 92
em UTF-8 ebd -> bc
em iso8859-15.Embora isso tenha as mesmas limitações já mencionadas como a
tr
solução oferecida por Stéphane Chazelas, é outra maneira de fazê-lo:RESULTADO
Eu despejo
stderr
para/dev/null
lá porquedd
também fornece estatísticas de todas as suas operações no2
descritor de arquivo. Isso pode ser útil dependendo do que você está fazendo, mas não foi para esta demonstração. Todas as outras coisas com as quais você pode fazerdd
ainda se aplicam, por exemplo:RESULTADO:
fonte
aBc
não é convertido emAbC
).Se seu objetivo principal é converter um arquivo de classe baixa para classe alta, por que você não usa
tr
eSTDOUT
para converter seu arquivo:Onde
FILENAME
está o seu arquivo original. OndeFILENAME2
está o seu arquivo de saída convertido.fonte
é
por exemplo (pelo menos no meu arquivo).usando
awk
:fonte
>file.txt
começaria truncando o arquivoruby
tem um método de string para isso, uso semelhante na linha de comando, comoperl
Veja também Ruby-doc Encoding
fonte
Mantenha simples coisa simples. O filtro projetado para traduzir caracteres é
tr
.fonte