Nota: YMMV neste. Não funciona para mim (versão 4.2.46 e 4.0.33 do GNU bash (e o mesmo comportamento 2.05b.0 mas o nocasematch não está implementado)) mesmo com o uso shopt -u nocasematch;. Desativar esse nocasematch faz com que [["fooBaR" == "FOObar"]] corresponda a OK, mas por dentro, estranhamente, [bz] é incorretamente correspondido por [AZ]. Bash é confundido com o duplo negativo ("nocasematch desestabilizador")! :-)
Estou faltando alguma coisa ou o seu último exemplo (no Bash) realmente faz algo completamente diferente? Ele funciona para "ABX", mas se você fizer word="Hi All"os outros exemplos, ele retornará ha, não hi all. Funciona apenas para as letras maiúsculas e pula as letras já em minúsculas.
Jangosteve # 1
26
Observe que apenas os exemplos tre awksão especificados no padrão POSIX.
Richard Hansen
178
tr '[:upper:]' '[:lower:]'usará o código do idioma atual para determinar equivalentes em maiúsculas / minúsculas, portanto, ele funcionará com códigos de idioma que usam letras com marcas diacríticas.
Richard Hansen
10
Como se obtém a saída para uma nova variável? Ou seja, eu quero que a string em minúsculas seja uma nova variável?
Adam Parkin
60
@Adam:b="$(echo $a | tr '[A-Z]' '[a-z]')"
Tino
435
No Bash 4:
Para minúsculas
$ string="A FEW WORDS"
$ echo "${string,}"
a FEW WORDS
$ echo "${string,,}"
a few words
$ echo "${string,,[AEIUO]}"
a FeWWoRDS
$ string="A Few Words"
$ declare -l string
$ string=$string; echo "$string"
a few words
Para maiúsculas
$ string="a few words"
$ echo "${string^}"
A few words
$ echo "${string^^}"
A FEW WORDS
$ echo "${string^^[aeiou]}"
A fEw wOrds
$ string="A Few Words"
$ declare -u string
$ string=$string; echo "$string"
A FEW WORDS
Alternar (não documentado, mas opcionalmente configurável em tempo de compilação)
$ string="A Few Words"
$ echo "${string~~}"
a fEW wORDS
$ string="A FEW WORDS"
$ echo "${string~}"
a FEW WORDS
$ string="a few words"
$ echo "${string~}"
A few words
Capitalizar (não documentado, mas opcionalmente configurável em tempo de compilação)
$ string="a few words"
$ declare -c string
$ string=$string
$ echo "$string"
A few words
Caso do título:
$ string="a few words"
$ string=($string)
$ string="${string[@]^}"
$ echo "$string"
A FewWords
$ declare -c string
$ string=(a few words)
$ echo "${string[@]}"
A FewWords
$ string="a FeW WOrdS"
$ string=${string,,}
$ string=${string~}
$ echo "$string"
A few words
Para desativar um declareatributo, use +. Por exemplo declare +c string,. Isso afeta as atribuições subseqüentes e não o valor atual.
As declareopções alteram o atributo da variável, mas não o conteúdo. As reatribuições nos meus exemplos atualizam o conteúdo para mostrar as alterações.
Editar:
Adicionado "alternar o primeiro caractere pela palavra" ( ${var~}), como sugerido por ghostdog74 .
Edit: Corrigido o comportamento do til para coincidir com o Bash 4.3.
Bastante bizzare, os operadores "^^" e ",," não funcionam com caracteres não ASCII, mas "~~" funciona ... Então string="łódź"; echo ${string~~}, retornará "ŁÓDŹ", mas echo ${string^^}retornará "łóDź". Mesmo em LC_ALL=pl_PL.utf-8. Isso está usando o bash 4.2.24.
Hubert Kario
2
@HubertKario: Isso é estranho. É o mesmo para mim no Bash 4.0.33 com a mesma string en_US.UTF-8. É um bug e eu relatei.
Pausado até novo aviso.
1
@HubertKario: Tente echo "$string" | tr '[:lower:]' '[:upper:]'. Provavelmente exibirá a mesma falha. Portanto, o problema não é, pelo menos em parte, o de Bash.
Pausado até novo aviso.
1
@DennisWilliamson: Sim, eu também notei isso (veja o comentário na resposta de Shuvalov). Eu diria apenas "esse material é apenas para ASCII", mas é o operador "~~" que funciona, por isso não é como se as tabelas de código e tradução ainda não estivessem lá ...
Hubert Kario
4
@HubertKario: O mantenedor do Bash reconheceu o erro e afirmou que ele será corrigido na próxima versão.
@ RichardHansen: trnão funciona para mim para caracteres que não são da ACII. Eu tenho o conjunto de localizações correto e os arquivos de localidade gerados. Tem alguma idéia do que eu poderia estar fazendo de errado?
Hubert Kario
FYI: Isso funcionou no Windows / Msys. Algumas das outras sugestões não o fizeram.
O +1 a="$(tr [A-Z] [a-z] <<< "$a")"parece mais fácil para mim. Eu ainda sou um iniciante ...
Sandeepan Nath 02/02
2
Eu recomendo fortemente a sedsolução; Eu tenho trabalhado em um ambiente que por algum motivo não tem tr, mas eu ainda tenho que encontrar um sistema, sem sed, além de uma grande parte do tempo que eu quero fazer isso eu acabei de fazer outra coisa em sedqualquer maneira para cadeia de lata os comandos juntos em uma única instrução (longa).
Haravikk
2
As expressões entre colchetes devem ser citadas. Em tr [A-Z] [a-z] A, o shell pode executar a expansão do nome do arquivo se houver nomes de arquivos consistindo em uma única letra ou se o nullgob estiver definido. tr "[A-Z]" "[a-z]" Ase comportará corretamente.
Dennis
2
@CamiloMartin, é um sistema BusyBox em que estou tendo esse problema, especificamente Synology NASes, mas também o encontrei em alguns outros sistemas. Ultimamente, venho desenvolvendo muitos scripts de shell de plataforma cruzada e, com o requisito de que nada extra seja instalado, isso torna as coisas muito complicadas! No entanto, eu ainda tenho que encontrar um sistema semsed
Haravikk
2
Observe que tr [A-Z] [a-z]está incorreto em quase todos os locais. por exemplo, na en-USlocalidade, A-Zé realmente o intervalo AaBbCcDdEeFfGgHh...XxYyZ.
fuz 31/01
44
Eu sei que este é um post antigo, mas eu respondi para outro site, então pensei em publicá-lo aqui:
UPPER -> lower : use python:
b=`echo "print '$a'.lower()" | python`
Ou Ruby:
b=`echo "print '$a'.downcase" | ruby`
Ou Perl (provavelmente o meu favorito):
b=`perl -e "print lc('$a');"`
Ou PHP:
b=`php -r "print strtolower('$a');"`
Ou Awk:
b=`echo "$a" | awk '{ print tolower($1) }'`
Ou Sed:
b=`echo "$a" | sed 's/./\L&/g'`
Ou Bash 4:
b=${a,,}
Ou NodeJS, se você o tiver (e estiver um pouco louco ...):
@ JESii ambos trabalham para mim superior -> inferior e inferior -> superior. Estou usando o sed 4.2.2 e o Bash 4.3.42 (1) no Debian Stretch de 64 bits.
Nettux
1
Oi, @ nettux443 ... Acabei de tentar a operação do bash novamente e ela ainda falha com a mensagem de erro "substituição incorreta". Eu estou no OSX usando o bash do homebrew: GNU bash, versão 4.3.42 (1) -release (x86_64-apple-darwin14.5.0)
JESii
5
Não use! Todos os exemplos que geram um script são extremamente frágeis; se o valor de acontiver uma aspas simples, você não apenas terá um comportamento defeituoso, mas um sério problema de segurança.
Tripleee
Eu gosto mais da solução sed, pois o sed é sempre onipresente.
Dudi Boy
Eu prefiro usar a solução dd. Por favor note que você precisa ser root para fazê-lo funcionar
Gostaria de receber o crédito pelo comando que desejo compartilhar, mas a verdade é que eu o obtive para meu próprio uso em http://commandlinefu.com . Tem a vantagem de que, se você cdacessar um diretório dentro de sua própria pasta pessoal, ele alterará todos os arquivos e pastas para minúsculas recursivamente, use com cuidado. É uma correção de linha de comando brilhante e especialmente útil para as multidões de álbuns que você armazenou em sua unidade.
Isso não funcionou para mim por qualquer motivo, embora pareça bem. Eu fiz isso funcionar como uma alternativa: encontrar. -exec / bin / bash -c 'mv {} `tr [AZ] [az] <<< {}`' \;
precisa
Isso precisa prenamede perl: dpkg -S "$(readlink -e /usr/bin/rename)"dáperl: /usr/bin/prename
Tino
4
Muitas respostas usando programas externos, o que realmente não está sendo usado Bash.
Se você sabe que terá o Bash4 disponível, use realmente a ${VAR,,}notação (é fácil e legal). Para o Bash anterior a 4 (meu Mac ainda usa o Bash 3.2, por exemplo). Usei a versão corrigida da resposta de @ ghostdog74 para criar uma versão mais portátil.
Você pode ligar lowercase 'my STRING'e obter uma versão em minúscula. Eu li comentários sobre como definir o resultado como um var, mas isso não é realmente portátil Bash, pois não podemos retornar strings. Imprimir é a melhor solução. Fácil de capturar com algo parecido var="$(lowercase $str)".
Como isso funciona
A maneira como isso funciona é obtendo a representação inteira ASCII de cada caractere com printfe então adding 32se upper-to->lower, ou subtracting 32se lower-to->upper. Em seguida, use printfnovamente para converter o número novamente em um caractere. Desde 'A' -to-> 'a'temos uma diferença de 32 caracteres.
Usando printfpara explicar:
$ printf "%d\n""'a"97
$ printf "%d\n""'A"65
97 - 65 = 32
E esta é a versão de trabalho com exemplos.
Observe os comentários no código, pois eles explicam muitas coisas:
#!/bin/bash# lowerupper.sh# Prints the lowercase version of a char
lowercaseChar(){case"$1"in[A-Z])
n=$(printf "%d""'$1")
n=$((n+32))
printf \\$(printf "%o""$n");;*)
printf "%s""$1";;esac}# Prints the lowercase version of a sequence of strings
lowercase(){
word="$@"for((i=0;i<${#word};i++));do
ch="${word:$i:1}"
lowercaseChar "$ch"done}# Prints the uppercase version of a char
uppercaseChar(){case"$1"in[a-z])
n=$(printf "%d""'$1")
n=$((n-32))
printf \\$(printf "%o""$n");;*)
printf "%s""$1";;esac}# Prints the uppercase version of a sequence of strings
uppercase(){
word="$@"for((i=0;i<${#word};i++));do
ch="${word:$i:1}"
uppercaseChar "$ch"done}# The functions will not add a new line, so use echo or# append it if you want a new line after printing# Printing stuff directly
lowercase "I AM the Walrus!"$'\n'
uppercase "I AM the Walrus!"$'\n'
echo "----------"# Printing a var
str="A StRing WITH mixed sTUFF!"
lowercase "$str"$'\n'
uppercase "$str"$'\n'
echo "----------"# Not quoting the var should also work, # since we use "$@" inside the functions
lowercase $str$'\n'
uppercase $str$'\n'
echo "----------"# Assigning to a var
myLowerVar="$(lowercase $str)"
myUpperVar="$(uppercase $str)"
echo "myLowerVar: $myLowerVar"
echo "myUpperVar: $myUpperVar"
echo "----------"# You can even do stuff likeif[['option 2'="$(lowercase 'OPTION 2')"]];then
echo "Fine! All the same!"else
echo "Ops! Not the same!"fi
exit 0
E os resultados depois de executar isso:
$ ./lowerupper.sh
i am the walrus!
I AM THE WALRUS!----------
a string with mixed stuff!
A STRING WITH MIXED STUFF!----------
a string with mixed stuff!
A STRING WITH MIXED STUFF!----------
myLowerVar: a string with mixed stuff!
myUpperVar: A STRING WITH MIXED STUFF!----------Fine!All the same!
Isso deve funcionar apenas para caracteres ASCII .
Para mim, tudo bem, pois sei que só passarei caracteres ASCII para ele.
Estou usando isso para algumas opções de CLI que não diferenciam maiúsculas de minúsculas, por exemplo.
A conversão de maiúsculas e minúsculas é feita apenas para alfabetos. Portanto, isso deve funcionar perfeitamente.
Estou focando na conversão de alfabetos entre az de maiúsculas para minúsculas. Quaisquer outros caracteres devem ser impressos apenas em stdout, pois são ...
Converte todo o texto no caminho / para / arquivo / nome do arquivo dentro do intervalo de az para AZ
Para converter letras minúsculas em maiúsculas
cat path/to/file/filename | tr 'a-z''A-Z'
Para converter de maiúsculas para minúsculas
cat path/to/file/filename | tr 'A-Z''a-z'
Por exemplo,
nome do arquivo:
my name is xyz
é convertido em:
MY NAME IS XYZ
Exemplo 2:
echo "my name is 123 karthik"| tr 'a-z''A-Z'# Output:# MY NAME IS 123 KARTHIK
Exemplo 3:
echo "my name is 123 &&^&& #@$#@%%& kAR2~thik"| tr 'a-z''A-Z'# Output:# MY NAME IS 123 &&^&& #@0@%%& KAR2~THIK
Se estiver usando v4, este é cozido-in . Caso contrário, aqui está uma solução simples e amplamente aplicável . Outras respostas (e comentários) sobre este tópico foram bastante úteis na criação do código abaixo.
# Like echo, but converts to lowercase
echolcase (){
tr [:upper:][:lower:]<<<"${*}"}# Takes one arg by reference (var name) and makes it lowercase
lcase (){eval"${1}"=\'$(echo ${!1//\'/"'\''"}| tr [:upper:][:lower:])\'
}
Notas:
Fazendo: a="Hi All"e então: lcase afará a mesma coisa que:a=$( echolcase "Hi All" )
Na função lcase, usar em ${!1//\'/"'\''"}vez de ${!1}permite que isso funcione mesmo quando a string possui aspas.
Não é ruim! Para uma análise do desempenho dessa abordagem, consulte minha resposta para métricas.
DeJay Clayton
3
Apesar de quantos anos essa pergunta tem e semelhante à resposta do technosaurus . Foi difícil encontrar uma solução que fosse portátil na maioria das plataformas (que eu uso) e nas versões mais antigas do bash. Também fiquei frustrado com matrizes, funções e uso de impressões, ecos e arquivos temporários para recuperar variáveis triviais. Até agora, isso funcionou muito bem para mim e pensei em compartilhar. Meus principais ambientes de teste são:
Lançamento do GNU bash, versão 4.1.2 (1) (x86_64-redhat-linux-gnu)
Lançamento do GNU bash, versão 3.2.57 (1) (sparc-sun-solaris2.10)
lcs="abcdefghijklmnopqrstuvwxyz"
ucs="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
input="Change Me To All Capitals"for(( i=0; i<"${#input}"; i++));do:for(( j=0; j<"${#lcs}"; j++));do:if[["${input:$i:1}"=="${lcs:$j:1}"]];then
input="${input/${input:$i:1}/${ucs:$j:1}}"fidonedone
Estilo C simples para loop para iterar pelas seqüências de caracteres. Para a linha abaixo, se você nunca viu nada assim antes,
foi aqui que eu aprendi isso . Nesse caso, a linha verifica se o char $ {input: $ i: 1} (minúsculo) existe na entrada e, se houver, substitui-o pelo dado char $ {ucs: $ j: 1} (maiúsculo) e o armazena de volta à entrada.
Isso é extremamente ineficiente, repetindo 650 vezes no exemplo acima e demorando 35 segundos para executar 1000 invocações na minha máquina. Para uma alternativa que faça um loop apenas 11 vezes e leve menos de 5 segundos para executar 1000 invocações, veja minha resposta alternativa.
DeJay Clayton #
1
Obrigado, embora isso deva ser óbvio apenas olhando para ele. Talvez as falhas de página sejam do tamanho da entrada e do número de iterações que você está executando. No entanto, eu gosto da sua solução.
precisa saber é o seguinte
3
Essa é uma variação muito mais rápida da abordagem do JaredTS486 que usa recursos nativos do Bash (incluindo versões do Bash <4.0) para otimizar sua abordagem.
Cronometrei 1.000 iterações dessa abordagem para uma sequência pequena (25 caracteres) e uma sequência maior (445 caracteres), tanto para conversões em minúsculas quanto em maiúsculas. Como as sequências de teste são predominantemente em minúsculas, as conversões em minúsculas geralmente são mais rápidas que em maiúsculas.
Comparei minha abordagem com várias outras respostas nesta página que são compatíveis com o Bash 3.2. Minha abordagem é muito mais eficiente do que a maioria das abordagens documentadas aqui e é ainda mais rápida do que trem vários casos.
Aqui estão os resultados de temporização para 1.000 iterações de 25 caracteres:
0,46s para minha abordagem em minúsculas; 0.96s para maiúsculas
75s para a abordagem de ghostdog74 em minúsculas; 669s para maiúsculas. É interessante notar o quão dramática é a diferença de desempenho entre um teste com correspondências predominantes e um teste com faltas predominantes
660s para a abordagem de JaredTS486 em minúsculas; 660s para maiúsculas. É interessante notar que essa abordagem gerou falhas contínuas de página (troca de memória) no Bash
A abordagem é simples: enquanto a string de entrada tem letras maiúsculas restantes, localize a próxima e substitua todas as instâncias dessa letra por sua variante minúscula. Repita até que todas as letras maiúsculas sejam substituídas.
Algumas características de desempenho da minha solução:
Usa apenas utilitários embutidos no shell, o que evita a sobrecarga de chamar utilitários binários externos em um novo processo
Evita subcascas, que sofrem penalidades de desempenho
Utiliza mecanismos de shell que são compilados e otimizados para desempenho, como substituição global de cadeias dentro de variáveis, ajuste de sufixos de variáveis e pesquisa e correspondência de expressões regulares. Esses mecanismos são muito mais rápidos do que iterando manualmente através de strings
Repete apenas o número de vezes que a contagem de caracteres correspondentes únicos deve ser convertida. Por exemplo, converter uma sequência que possui três caracteres maiúsculos diferentes em minúsculas requer apenas três iterações de loop. Para o alfabeto ASCII pré-configurado, o número máximo de iterações de loop é 26
UCSe LCSpode ser aumentado com caracteres adicionais
Respostas:
Existem várias maneiras:
Padrão POSIX
tr
AWK
Não POSIX
Você pode ter problemas de portabilidade com os seguintes exemplos:
Bash 4.0
sed
Perl
Bater
Nota: YMMV neste. Não funciona para mim (versão 4.2.46 e 4.0.33 do GNU bash (e o mesmo comportamento 2.05b.0 mas o nocasematch não está implementado)) mesmo com o uso
shopt -u nocasematch;
. Desativar esse nocasematch faz com que [["fooBaR" == "FOObar"]] corresponda a OK, mas por dentro, estranhamente, [bz] é incorretamente correspondido por [AZ]. Bash é confundido com o duplo negativo ("nocasematch desestabilizador")! :-)fonte
word="Hi All"
os outros exemplos, ele retornaráha
, nãohi all
. Funciona apenas para as letras maiúsculas e pula as letras já em minúsculas.tr
eawk
são especificados no padrão POSIX.tr '[:upper:]' '[:lower:]'
usará o código do idioma atual para determinar equivalentes em maiúsculas / minúsculas, portanto, ele funcionará com códigos de idioma que usam letras com marcas diacríticas.b="$(echo $a | tr '[A-Z]' '[a-z]')"
No Bash 4:
Para minúsculas
Para maiúsculas
Alternar (não documentado, mas opcionalmente configurável em tempo de compilação)
Capitalizar (não documentado, mas opcionalmente configurável em tempo de compilação)
Caso do título:
Para desativar um
declare
atributo, use+
. Por exemplodeclare +c string
,. Isso afeta as atribuições subseqüentes e não o valor atual.As
declare
opções alteram o atributo da variável, mas não o conteúdo. As reatribuições nos meus exemplos atualizam o conteúdo para mostrar as alterações.Editar:
Adicionado "alternar o primeiro caractere pela palavra" (
${var~}
), como sugerido por ghostdog74 .Edit: Corrigido o comportamento do til para coincidir com o Bash 4.3.
fonte
string="łódź"; echo ${string~~}
, retornará "ŁÓDŹ", masecho ${string^^}
retornará "łóDź". Mesmo emLC_ALL=pl_PL.utf-8
. Isso está usando o bash 4.2.24.en_US.UTF-8
. É um bug e eu relatei.echo "$string" | tr '[:lower:]' '[:upper:]'
. Provavelmente exibirá a mesma falha. Portanto, o problema não é, pelo menos em parte, o de Bash.fonte
tr
não funciona para mim para caracteres que não são da ACII. Eu tenho o conjunto de localizações correto e os arquivos de localidade gerados. Tem alguma idéia do que eu poderia estar fazendo de errado?[:upper:]
necessário?tr :
AWK :
sed :
fonte
a="$(tr [A-Z] [a-z] <<< "$a")"
parece mais fácil para mim. Eu ainda sou um iniciante ...sed
solução; Eu tenho trabalhado em um ambiente que por algum motivo não temtr
, mas eu ainda tenho que encontrar um sistema, semsed
, além de uma grande parte do tempo que eu quero fazer isso eu acabei de fazer outra coisa emsed
qualquer maneira para cadeia de lata os comandos juntos em uma única instrução (longa).tr [A-Z] [a-z] A
, o shell pode executar a expansão do nome do arquivo se houver nomes de arquivos consistindo em uma única letra ou se o nullgob estiver definido.tr "[A-Z]" "[a-z]" A
se comportará corretamente.sed
tr [A-Z] [a-z]
está incorreto em quase todos os locais. por exemplo, naen-US
localidade,A-Z
é realmente o intervaloAaBbCcDdEeFfGgHh...XxYyZ
.Eu sei que este é um post antigo, mas eu respondi para outro site, então pensei em publicá-lo aqui:
UPPER -> lower : use python:
Ou Ruby:
Ou Perl (provavelmente o meu favorito):
Ou PHP:
Ou Awk:
Ou Sed:
Ou Bash 4:
Ou NodeJS, se você o tiver (e estiver um pouco louco ...):
Você também pode usar
dd
(mas eu não usaria!):inferior -> SUPERIOR :
use python:
Ou Ruby:
Ou Perl (provavelmente o meu favorito):
Ou PHP:
Ou Awk:
Ou Sed:
Ou Bash 4:
Ou NodeJS, se você o tiver (e estiver um pouco louco ...):
Você também pode usar
dd
(mas eu não usaria!):Além disso, quando você diz 'shell', estou assumindo que você quer dizer,
bash
mas se você pode usá-zsh
lo, é tão fácil quantopara minúsculas e
para maiúsculas.
fonte
a
contiver uma aspas simples, você não apenas terá um comportamento defeituoso, mas um sério problema de segurança.No zsh:
Conseguiu amar o zsh!
fonte
echo ${(C)a} #Upcase the first char only
Usando o GNU
sed
:Exemplo:
fonte
Pre Bash 4.0
Bash Abaixe a caixa de uma string e atribua à variável
fonte
echo
tubos: use$(tr '[:upper:]' '[:lower:]' <<<"$VARIABLE")
Para um shell padrão (sem bashisms) usando apenas builtins:
E para maiúsculas:
fonte
${var:1:1}
são um Bashism.No bash 4, você pode usar o typeset
Exemplo:
fonte
Você pode tentar isso
ref: http://wiki.workassis.com/shell-script-convert-text-to-lowercase-and-uppercase/
fonte
Expressão regular
Gostaria de receber o crédito pelo comando que desejo compartilhar, mas a verdade é que eu o obtive para meu próprio uso em http://commandlinefu.com . Tem a vantagem de que, se você
cd
acessar um diretório dentro de sua própria pasta pessoal, ele alterará todos os arquivos e pastas para minúsculas recursivamente, use com cuidado. É uma correção de linha de comando brilhante e especialmente útil para as multidões de álbuns que você armazenou em sua unidade.Você pode especificar um diretório no lugar do ponto (.) Após a localização, que indica o diretório atual ou o caminho completo.
Espero que essa solução seja útil. A única coisa que esse comando não faz é substituir espaços por sublinhados - bem, talvez outra hora.
fonte
prename
deperl
:dpkg -S "$(readlink -e /usr/bin/rename)"
dáperl: /usr/bin/prename
Muitas respostas usando programas externos, o que realmente não está sendo usado
Bash
.Se você sabe que terá o Bash4 disponível, use realmente a
${VAR,,}
notação (é fácil e legal). Para o Bash anterior a 4 (meu Mac ainda usa o Bash 3.2, por exemplo). Usei a versão corrigida da resposta de @ ghostdog74 para criar uma versão mais portátil.Você pode ligar
lowercase 'my STRING'
e obter uma versão em minúscula. Eu li comentários sobre como definir o resultado como um var, mas isso não é realmente portátilBash
, pois não podemos retornar strings. Imprimir é a melhor solução. Fácil de capturar com algo parecidovar="$(lowercase $str)"
.Como isso funciona
A maneira como isso funciona é obtendo a representação inteira ASCII de cada caractere com
printf
e entãoadding 32
seupper-to->lower
, ousubtracting 32
selower-to->upper
. Em seguida, useprintf
novamente para converter o número novamente em um caractere. Desde'A' -to-> 'a'
temos uma diferença de 32 caracteres.Usando
printf
para explicar:97 - 65 = 32
E esta é a versão de trabalho com exemplos.
Observe os comentários no código, pois eles explicam muitas coisas:
E os resultados depois de executar isso:
Isso deve funcionar apenas para caracteres ASCII .
Para mim, tudo bem, pois sei que só passarei caracteres ASCII para ele.
Estou usando isso para algumas opções de CLI que não diferenciam maiúsculas de minúsculas, por exemplo.
fonte
A conversão de maiúsculas e minúsculas é feita apenas para alfabetos. Portanto, isso deve funcionar perfeitamente.
Estou focando na conversão de alfabetos entre az de maiúsculas para minúsculas. Quaisquer outros caracteres devem ser impressos apenas em stdout, pois são ...
Converte todo o texto no caminho / para / arquivo / nome do arquivo dentro do intervalo de az para AZ
Para converter letras minúsculas em maiúsculas
Para converter de maiúsculas para minúsculas
Por exemplo,
nome do arquivo:
é convertido em:
Exemplo 2:
Exemplo 3:
fonte
Se estiver usando v4, este é cozido-in . Caso contrário, aqui está uma solução simples e amplamente aplicável . Outras respostas (e comentários) sobre este tópico foram bastante úteis na criação do código abaixo.
Notas:
a="Hi All"
e então:lcase a
fará a mesma coisa que:a=$( echolcase "Hi All" )
${!1//\'/"'\''"}
vez de${!1}
permite que isso funcione mesmo quando a string possui aspas.fonte
Para versões do Bash anteriores à 4.0, essa versão deve ser mais rápida (pois não bifurca / executa nenhum comando):
a resposta do technosaurus também tinha potencial, embora funcionasse corretamente para mim.
fonte
Apesar de quantos anos essa pergunta tem e semelhante à resposta do technosaurus . Foi difícil encontrar uma solução que fosse portátil na maioria das plataformas (que eu uso) e nas versões mais antigas do bash. Também fiquei frustrado com matrizes, funções e uso de impressões, ecos e arquivos temporários para recuperar variáveis triviais. Até agora, isso funcionou muito bem para mim e pensei em compartilhar. Meus principais ambientes de teste são:
Estilo C simples para loop para iterar pelas seqüências de caracteres. Para a linha abaixo, se você nunca viu nada assim antes, foi aqui que eu aprendi isso . Nesse caso, a linha verifica se o char $ {input: $ i: 1} (minúsculo) existe na entrada e, se houver, substitui-o pelo dado char $ {ucs: $ j: 1} (maiúsculo) e o armazena de volta à entrada.
fonte
Essa é uma variação muito mais rápida da abordagem do JaredTS486 que usa recursos nativos do Bash (incluindo versões do Bash <4.0) para otimizar sua abordagem.
Cronometrei 1.000 iterações dessa abordagem para uma sequência pequena (25 caracteres) e uma sequência maior (445 caracteres), tanto para conversões em minúsculas quanto em maiúsculas. Como as sequências de teste são predominantemente em minúsculas, as conversões em minúsculas geralmente são mais rápidas que em maiúsculas.
Comparei minha abordagem com várias outras respostas nesta página que são compatíveis com o Bash 3.2. Minha abordagem é muito mais eficiente do que a maioria das abordagens documentadas aqui e é ainda mais rápida do que
tr
em vários casos.Aqui estão os resultados de temporização para 1.000 iterações de 25 caracteres:
tr
minúsculas; 3.81s para maiúsculasResultados de tempo para 1.000 iterações de 445 caracteres (consistindo no poema "The Robin" de Witter Bynner):
tr
minúsculas; 4s para maiúsculasSolução:
A abordagem é simples: enquanto a string de entrada tem letras maiúsculas restantes, localize a próxima e substitua todas as instâncias dessa letra por sua variante minúscula. Repita até que todas as letras maiúsculas sejam substituídas.
Algumas características de desempenho da minha solução:
UCS
eLCS
pode ser aumentado com caracteres adicionaisfonte
Para armazenar a sequência transformada em uma variável. A seguir trabalhou para mim -
$SOURCE_NAME
para$TARGET_NAME
fonte
Maneira simples
fonte