Remarque: YMMV sur celui-ci. Ne fonctionne pas pour moi (GNU bash version 4.2.46 et 4.0.33 (et même comportement 2.05b.0 mais nocasematch n'est pas implémenté)) même avec using shopt -u nocasematch;. Ne pas définir que nocasematch fait que [["fooBaR" == "FOObar"]] correspond à OK MAIS étrangement à l'intérieur de la casse [bz] est incorrectement mis en correspondance par [AZ]. Bash est confondu par le double négatif ("unsetting nocasematch")! :-)
Suis-je en train de manquer quelque chose, ou votre dernier exemple (dans Bash) fait-il quelque chose de complètement différent? Cela fonctionne pour "ABX", mais si vous faites word="Hi All"comme les autres exemples, il revient ha, non hi all. Il ne fonctionne que pour les lettres majuscules et ignore les lettres déjà en minuscules.
jangosteve
26
Notez que seuls les exemples tret awksont spécifiés dans la norme POSIX.
Richard Hansen
178
tr '[:upper:]' '[:lower:]'utilisera les paramètres régionaux actuels pour déterminer les équivalents majuscules / minuscules, donc cela fonctionnera avec les paramètres régionaux qui utilisent des lettres avec des signes diacritiques.
Richard Hansen
10
Comment obtient-on la sortie dans une nouvelle variable? C'est-à-dire que je veux la chaîne en minuscule dans une nouvelle variable?
Adam Parkin
60
@Adam:b="$(echo $a | tr '[A-Z]' '[a-z]')"
Tino
435
Dans Bash 4:
Pour minuscule
$ 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
En majuscules
$ 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
Toggle (non documenté, mais configurable en option au moment de la compilation)
$ 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
Capitaliser (non documenté, mais configurable en option au moment de la compilation)
$ string="a few words"
$ declare -c string
$ string=$string
$ echo "$string"
A few words
Cas de titre:
$ 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
Pour désactiver un declareattribut, utilisez +. Par exemple declare +c string,. Cela affecte les affectations suivantes et non la valeur actuelle.
Les declareoptions modifient l'attribut de la variable, mais pas le contenu. Les réaffectations dans mes exemples mettent à jour le contenu pour montrer les changements.
Éditer:
Ajout de "basculer le premier caractère par mot" ( ${var~}) comme suggéré par ghostdog74 .
Edit: comportement tilde corrigé pour correspondre à Bash 4.3.
Assez bizzare, les opérateurs "^^" et ",," ne fonctionnent pas sur les caractères non ASCII mais "~~" le fait ... Donc string="łódź"; echo ${string~~}, retournera "ŁÓDŹ", mais echo ${string^^}renverra "łóDź". Même en LC_ALL=pl_PL.utf-8. Cela utilise bash 4.2.24.
Hubert Kario
2
@HubertKario: C'est bizarre. C'est la même chose pour moi dans Bash 4.0.33 avec la même chaîne en_US.UTF-8. C'est un bug et je l'ai signalé.
pause jusqu'à nouvel ordre.
1
@HubertKario: Essayez echo "$string" | tr '[:lower:]' '[:upper:]'. Il présentera probablement le même échec. Le problème n'est donc pas au moins en partie celui de Bash.
pause jusqu'à nouvel ordre.
1
@ DennisWilliamson: Oui, je l'ai remarqué aussi (voir le commentaire de la réponse Shuvalov). Je dirais juste, "ce truc est seulement pour ASCII", mais c'est l'opérateur "~~" qui fonctionne, donc ce n'est pas comme si le code et les tables de traduction n'étaient pas déjà là ...
Hubert Kario
4
@HubertKario: Le mainteneur de Bash a reconnu le bogue et a déclaré qu'il sera corrigé dans la prochaine version.
@RichardHansen: trne fonctionne pas pour moi pour les personnages non-ACII. J'ai un ensemble de paramètres régionaux correct et des fichiers de paramètres régionaux générés. Avez-vous une idée de ce que je pourrais faire de mal?
Hubert Kario
FYI: Cela a fonctionné sur Windows / Msys. Certaines autres suggestions ne l'ont pas fait.
+1 a="$(tr [A-Z] [a-z] <<< "$a")"me semble le plus simple. Je suis toujours un débutant ...
Sandeepan Nath
2
Je recommande fortement la sedsolution; J'ai travaillé dans un environnement qui, pour une raison quelconque, n'en a pas, trmais je n'ai pas encore trouvé de système sans sed, et la plupart du temps je veux le faire, je viens de faire quelque chose d'autre de sedtoute façon, donc je peux enchaîner les commandes ensemble dans une seule instruction (longue).
Haravikk
2
Les expressions entre crochets doivent être citées. Dans tr [A-Z] [a-z] A, le shell peut effectuer une expansion du nom de fichier s'il existe des noms de fichiers composés d'une seule lettre ou si nullgob est défini. tr "[A-Z]" "[a-z]" Ase comportera correctement.
Dennis
2
@CamiloMartin, c'est un système BusyBox où j'ai ce problème, en particulier les Synology NAS, mais je l'ai rencontré sur quelques autres systèmes également. J'ai fait beaucoup de scripts shell multiplateforme récemment, et avec l'exigence que rien de plus ne soit installé, cela rend les choses très délicates! Cependant, je n'ai pas encore rencontré de système sanssed
Haravikk
2
Notez que tr [A-Z] [a-z]c'est incorrect dans presque tous les environnements locaux. par exemple, dans les en-USparamètres régionaux, A-Zest en fait l'intervalle AaBbCcDdEeFfGgHh...XxYyZ.
fuz
44
Je sais que c'est un article ancien mais j'ai fait cette réponse pour un autre site, alors j'ai pensé le publier ici:
UPPER -> lower : utilisez python:
b=`echo "print '$a'.lower()" | python`
Ou Ruby:
b=`echo "print '$a'.downcase" | ruby`
Ou Perl (probablement mon préféré):
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 si vous l'avez (et êtes un peu fou ...):
@JESii fonctionne pour moi en haut -> en bas et en bas -> en haut. J'utilise sed 4.2.2 et Bash 4.3.42 (1) sur Debian Stretch 64 bits.
nettux
1
Salut, @ nettux443 ... Je viens de réessayer l'opération bash et elle échoue toujours pour moi avec le message d'erreur "mauvaise substitution". Je suis sur OSX en utilisant bash de homebrew: GNU bash, version 4.3.42 (1) -release (x86_64-apple-darwin14.5.0)
JESii
5
Ne pas utiliser! Tous les exemples qui génèrent un script sont extrêmement fragiles; si la valeur de acontient une seule citation, vous avez non seulement un comportement défectueux, mais un grave problème de sécurité.
tripleee
J'aime le plus la solution sed, car sed est toujours omniprésente.
Dudi Boy
Je préfère utiliser la solution dd. Veuillez noter que vous devez être root pour le faire fonctionner
Je voudrais prendre le crédit de la commande que je souhaite partager, mais la vérité est que je l'ai obtenue pour mon propre usage sur http://commandlinefu.com . Il a l'avantage que si vous accédez cdà n'importe quel répertoire de votre propre dossier de départ, cela changera tous les fichiers et dossiers en minuscules de manière récursive, veuillez les utiliser avec prudence. C'est une solution brillante en ligne de commande et particulièrement utile pour les multitudes d'albums que vous avez stockés sur votre disque.
Vous pouvez spécifier un répertoire à la place du point (.) Après la recherche qui indique le répertoire actuel ou le chemin complet.
J'espère que cette solution s'avère utile la seule chose que cette commande ne fait pas est de remplacer les espaces par des traits de soulignement - eh bien une autre fois peut-être.
Cela n'a pas fonctionné pour moi pour une raison quelconque, bien que cela semble bien. J'ai réussi à faire en sorte que cela fonctionne comme une alternative: trouver. -exec / bin / bash -c 'mv {} `tr [AZ] [az] <<< {}`' \;
Beaucoup de réponses en utilisant des programmes externes, ce qui n'est pas vraiment utile Bash.
Si vous savez que Bash4 sera disponible, vous devriez vraiment utiliser la ${VAR,,}notation (c'est facile et cool). Pour Bash avant 4 (mon Mac utilise toujours Bash 3.2 par exemple). J'ai utilisé la version corrigée de la réponse de @ ghostdog74 pour créer une version plus portable.
Celui que vous pouvez appeler lowercase 'my STRING'et obtenir une version en minuscules. J'ai lu des commentaires sur la définition du résultat sur une variable, mais ce n'est pas vraiment portable Bash, car nous ne pouvons pas retourner de chaînes. L'imprimer est la meilleure solution. Facile à capturer avec quelque chose comme var="$(lowercase $str)".
Comment ça marche
La façon dont cela fonctionne consiste à obtenir la représentation entière ASCII de chaque caractère avec printfpuis adding 32si upper-to->lower, ou subtracting 32si lower-to->upper. Ensuite, utilisez à printfnouveau pour reconvertir le nombre en caractère. De 'A' -to-> 'a'nous avons une différence de 32 caractères.
Utiliser printfpour expliquer:
$ printf "%d\n""'a"97
$ printf "%d\n""'A"65
97 - 65 = 32
Et ceci est la version de travail avec des exemples.
Veuillez noter les commentaires dans le code, car ils expliquent beaucoup de choses:
#!/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
Et les résultats après avoir exécuté ceci:
$ ./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!
Cela ne devrait cependant fonctionner que pour les caractères ASCII .
Pour moi, c'est bien, car je sais que je ne lui transmettrai que des caractères ASCII.
Je l'utilise pour certaines options CLI insensibles à la casse, par exemple.
La conversion de la casse est effectuée uniquement pour les alphabets. Donc, cela devrait fonctionner parfaitement.
Je me concentre sur la conversion des alphabets entre az de majuscules en minuscules. Tout autre caractère doit simplement être imprimé dans stdout tel quel ...
Convertit tout le texte du chemin / vers / fichier / nom de fichier dans la plage az en AZ
Pour convertir des minuscules en majuscules
cat path/to/file/filename | tr 'a-z''A-Z'
Pour la conversion de majuscules en minuscules
cat path/to/file/filename | tr 'A-Z''a-z'
Par exemple,
nom de fichier:
my name is xyz
est converti en:
MY NAME IS XYZ
Exemple 2:
echo "my name is 123 karthik"| tr 'a-z''A-Z'# Output:# MY NAME IS 123 KARTHIK
Exemple 3:
echo "my name is 123 &&^&& #@$#@%%& kAR2~thik"| tr 'a-z''A-Z'# Output:# MY NAME IS 123 &&^&& #@0@%%& KAR2~THIK
Si vous utilisez v4, cela est intégré . Sinon, voici une solution simple et largement applicable . D'autres réponses (et commentaires) sur ce fil ont été très utiles pour créer le code ci-dessous.
# 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:])\'
}
Remarques:
Faire: a="Hi All"et ensuite: lcase afera la même chose que:a=$( echolcase "Hi All" )
Dans la fonction lcase, l'utilisation de ${!1//\'/"'\''"}au lieu de ${!1}permet à cela de fonctionner même lorsque la chaîne a des guillemets.
Pas mal! Pour une analyse des performances de cette approche, veuillez consulter ma réponse pour les mesures.
Dejay Clayton
3
Malgré l'âge de cette question et similaire à cette réponse du technosaurus . J'ai eu du mal à trouver une solution portable sur la plupart des plates-formes (que j'utilise) ainsi que sur les anciennes versions de bash. J'ai également été frustré par les tableaux, les fonctions et l'utilisation des impressions, des échos et des fichiers temporaires pour récupérer des variables triviales. Cela fonctionne très bien pour moi jusqu'à présent, je pensais que je partagerais. Mes principaux environnements de test sont:
GNU bash, version 4.1.2 (1) -release (x86_64-redhat-linux-gnu)
GNU bash, version 3.2.57 (1) -release (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
Style C simple pour une boucle pour parcourir les cordes. Pour la ligne ci-dessous, si vous n'avez jamais rien vu de tel auparavant,
c'est là que j'ai appris cela . Dans ce cas, la ligne vérifie si le caractère $ {input: $ i: 1} (minuscule) existe en entrée et si c'est le cas le remplace par le caractère donné $ {ucs: $ j: 1} (majuscule) et le stocke en entrée.
Ceci est extrêmement inefficace, bouclant 650 fois dans votre exemple ci-dessus et prenant 35 secondes pour exécuter 1000 invocations sur ma machine. Pour une alternative qui boucle seulement 11 fois et prend moins de 5 secondes pour exécuter 1000 invocations, voir ma réponse alternative.
Dejay Clayton
1
Merci, bien que cela devrait être évident juste en le regardant. Les défauts de page sont peut-être dus à la taille d'entrée et au nombre d'itérations que vous exécutez. Néanmoins, j'aime votre solution.
JaredTS486
3
Il s'agit d'une variante beaucoup plus rapide de l'approche de JaredTS486 qui utilise les capacités natives de Bash (y compris les versions Bash <4.0) pour optimiser son approche.
J'ai chronométré 1000 itérations de cette approche pour une petite chaîne (25 caractères) et une chaîne plus grande (445 caractères), à la fois pour les conversions en minuscules et en majuscules. Étant donné que les chaînes de test sont principalement en minuscules, les conversions en minuscules sont généralement plus rapides qu'en majuscules.
J'ai comparé mon approche avec plusieurs autres réponses sur cette page qui sont compatibles avec Bash 3.2. Mon approche est beaucoup plus performante que la plupart des approches documentées ici, et est encore plus rapide que trdans plusieurs cas.
Voici les résultats de chronométrage pour 1000 itérations de 25 caractères:
0,46s pour mon approche des minuscules; 0,96 s pour les majuscules
75s pour 75s l' approche de ghostdog74 en minuscules; 669 pour les majuscules. Il est intéressant de noter à quel point la différence de performances est spectaculaire entre un test avec des correspondances prédominantes et un test avec des ratés prédominants
660 pour l'approche de JaredTS486 en minuscules; 660 pour les majuscules. Il est intéressant de noter que cette approche a généré des défauts de page continus (échange de mémoire) dans Bash
L'approche est simple: alors que la chaîne d'entrée contient toutes les lettres majuscules restantes, recherchez la suivante et remplacez toutes les instances de cette lettre par sa variante minuscule. Répétez jusqu'à ce que toutes les lettres majuscules soient remplacées.
Quelques caractéristiques de performance de ma solution:
Utilise uniquement des utilitaires intégrés au shell, ce qui évite la surcharge d'invoquer des utilitaires binaires externes dans un nouveau processus
Évite les sous-coques, qui entraînent des pénalités de performance
Utilise des mécanismes de shell qui sont compilés et optimisés pour les performances, tels que le remplacement global de chaînes dans les variables, le découpage des suffixes variables et la recherche et la correspondance d'expressions régulières. Ces mécanismes sont beaucoup plus rapides que l'itération manuelle via des chaînes
Boucle uniquement le nombre de fois requis par le nombre de caractères correspondants uniques à convertir. Par exemple, la conversion d'une chaîne contenant trois caractères majuscules différents en minuscules ne nécessite que 3 itérations de boucle. Pour l'alphabet ASCII préconfiguré, le nombre maximal d'itérations de boucle est de 26
UCSet LCSpeut être augmenté de caractères supplémentaires
Réponses:
Il existe différentes manières:
Norme POSIX
tr
AWK
Non-POSIX
Vous pouvez rencontrer des problèmes de portabilité avec les exemples suivants:
Bash 4.0
sed
Perl
Frapper
Remarque: YMMV sur celui-ci. Ne fonctionne pas pour moi (GNU bash version 4.2.46 et 4.0.33 (et même comportement 2.05b.0 mais nocasematch n'est pas implémenté)) même avec using
shopt -u nocasematch;
. Ne pas définir que nocasematch fait que [["fooBaR" == "FOObar"]] correspond à OK MAIS étrangement à l'intérieur de la casse [bz] est incorrectement mis en correspondance par [AZ]. Bash est confondu par le double négatif ("unsetting nocasematch")! :-)la source
word="Hi All"
comme les autres exemples, il revientha
, nonhi all
. Il ne fonctionne que pour les lettres majuscules et ignore les lettres déjà en minuscules.tr
etawk
sont spécifiés dans la norme POSIX.tr '[:upper:]' '[:lower:]'
utilisera les paramètres régionaux actuels pour déterminer les équivalents majuscules / minuscules, donc cela fonctionnera avec les paramètres régionaux qui utilisent des lettres avec des signes diacritiques.b="$(echo $a | tr '[A-Z]' '[a-z]')"
Dans Bash 4:
Pour minuscule
En majuscules
Toggle (non documenté, mais configurable en option au moment de la compilation)
Capitaliser (non documenté, mais configurable en option au moment de la compilation)
Cas de titre:
Pour désactiver un
declare
attribut, utilisez+
. Par exempledeclare +c string
,. Cela affecte les affectations suivantes et non la valeur actuelle.Les
declare
options modifient l'attribut de la variable, mais pas le contenu. Les réaffectations dans mes exemples mettent à jour le contenu pour montrer les changements.Éditer:
Ajout de "basculer le premier caractère par mot" (
${var~}
) comme suggéré par ghostdog74 .Edit: comportement tilde corrigé pour correspondre à Bash 4.3.
la source
string="łódź"; echo ${string~~}
, retournera "ŁÓDŹ", maisecho ${string^^}
renverra "łóDź". Même enLC_ALL=pl_PL.utf-8
. Cela utilise bash 4.2.24.en_US.UTF-8
. C'est un bug et je l'ai signalé.echo "$string" | tr '[:lower:]' '[:upper:]'
. Il présentera probablement le même échec. Le problème n'est donc pas au moins en partie celui de Bash.la source
tr
ne fonctionne pas pour moi pour les personnages non-ACII. J'ai un ensemble de paramètres régionaux correct et des fichiers de paramètres régionaux générés. Avez-vous une idée de ce que je pourrais faire de mal?[:upper:]
nécessaire?tr :
AWK :
sed :
la source
a="$(tr [A-Z] [a-z] <<< "$a")"
me semble le plus simple. Je suis toujours un débutant ...sed
solution; J'ai travaillé dans un environnement qui, pour une raison quelconque, n'en a pas,tr
mais je n'ai pas encore trouvé de système sanssed
, et la plupart du temps je veux le faire, je viens de faire quelque chose d'autre desed
toute façon, donc je peux enchaîner les commandes ensemble dans une seule instruction (longue).tr [A-Z] [a-z] A
, le shell peut effectuer une expansion du nom de fichier s'il existe des noms de fichiers composés d'une seule lettre ou si nullgob est défini.tr "[A-Z]" "[a-z]" A
se comportera correctement.sed
tr [A-Z] [a-z]
c'est incorrect dans presque tous les environnements locaux. par exemple, dans lesen-US
paramètres régionaux,A-Z
est en fait l'intervalleAaBbCcDdEeFfGgHh...XxYyZ
.Je sais que c'est un article ancien mais j'ai fait cette réponse pour un autre site, alors j'ai pensé le publier ici:
UPPER -> lower : utilisez python:
Ou Ruby:
Ou Perl (probablement mon préféré):
Ou PHP:
Ou Awk:
Ou Sed:
Ou Bash 4:
Ou NodeJS si vous l'avez (et êtes un peu fou ...):
Vous pouvez également utiliser
dd
(mais je ne le ferais pas!):inférieur -> SUPÉRIEUR :
utilisez python:
Ou Ruby:
Ou Perl (probablement mon préféré):
Ou PHP:
Ou Awk:
Ou Sed:
Ou Bash 4:
Ou NodeJS si vous l'avez (et êtes un peu fou ...):
Vous pouvez également utiliser
dd
(mais je ne le ferais pas!):Aussi quand vous dites «shell», je suppose que vous voulez dire,
bash
mais si vous pouvez l'utiliser,zsh
c'est aussi simple quepour les minuscules et
pour les majuscules.
la source
a
contient une seule citation, vous avez non seulement un comportement défectueux, mais un grave problème de sécurité.En zsh:
Je dois aimer zsh!
la source
echo ${(C)a} #Upcase the first char only
Utilisation de GNU
sed
:Exemple:
la source
Pre Bash 4.0
Bash Abaissez la casse d'une chaîne et affectez-la à une variable
la source
echo
tuyaux: utilisez$(tr '[:upper:]' '[:lower:]' <<<"$VARIABLE")
Pour un shell standard (sans bashismes) utilisant uniquement des builtins:
Et pour les majuscules:
la source
${var:1:1}
sont un bashisme.Dans bash 4, vous pouvez utiliser typeset
Exemple:
la source
Vous pouvez essayer ceci
réf: http://wiki.workassis.com/shell-script-convert-text-to-lowercase-and-uppercase/
la source
Expression régulière
Je voudrais prendre le crédit de la commande que je souhaite partager, mais la vérité est que je l'ai obtenue pour mon propre usage sur http://commandlinefu.com . Il a l'avantage que si vous accédez
cd
à n'importe quel répertoire de votre propre dossier de départ, cela changera tous les fichiers et dossiers en minuscules de manière récursive, veuillez les utiliser avec prudence. C'est une solution brillante en ligne de commande et particulièrement utile pour les multitudes d'albums que vous avez stockés sur votre disque.Vous pouvez spécifier un répertoire à la place du point (.) Après la recherche qui indique le répertoire actuel ou le chemin complet.
J'espère que cette solution s'avère utile la seule chose que cette commande ne fait pas est de remplacer les espaces par des traits de soulignement - eh bien une autre fois peut-être.
la source
prename
deperl
:dpkg -S "$(readlink -e /usr/bin/rename)"
donneperl: /usr/bin/prename
Beaucoup de réponses en utilisant des programmes externes, ce qui n'est pas vraiment utile
Bash
.Si vous savez que Bash4 sera disponible, vous devriez vraiment utiliser la
${VAR,,}
notation (c'est facile et cool). Pour Bash avant 4 (mon Mac utilise toujours Bash 3.2 par exemple). J'ai utilisé la version corrigée de la réponse de @ ghostdog74 pour créer une version plus portable.Celui que vous pouvez appeler
lowercase 'my STRING'
et obtenir une version en minuscules. J'ai lu des commentaires sur la définition du résultat sur une variable, mais ce n'est pas vraiment portableBash
, car nous ne pouvons pas retourner de chaînes. L'imprimer est la meilleure solution. Facile à capturer avec quelque chose commevar="$(lowercase $str)"
.Comment ça marche
La façon dont cela fonctionne consiste à obtenir la représentation entière ASCII de chaque caractère avec
printf
puisadding 32
siupper-to->lower
, ousubtracting 32
silower-to->upper
. Ensuite, utilisez àprintf
nouveau pour reconvertir le nombre en caractère. De'A' -to-> 'a'
nous avons une différence de 32 caractères.Utiliser
printf
pour expliquer:97 - 65 = 32
Et ceci est la version de travail avec des exemples.
Veuillez noter les commentaires dans le code, car ils expliquent beaucoup de choses:
Et les résultats après avoir exécuté ceci:
Cela ne devrait cependant fonctionner que pour les caractères ASCII .
Pour moi, c'est bien, car je sais que je ne lui transmettrai que des caractères ASCII.
Je l'utilise pour certaines options CLI insensibles à la casse, par exemple.
la source
La conversion de la casse est effectuée uniquement pour les alphabets. Donc, cela devrait fonctionner parfaitement.
Je me concentre sur la conversion des alphabets entre az de majuscules en minuscules. Tout autre caractère doit simplement être imprimé dans stdout tel quel ...
Convertit tout le texte du chemin / vers / fichier / nom de fichier dans la plage az en AZ
Pour convertir des minuscules en majuscules
Pour la conversion de majuscules en minuscules
Par exemple,
nom de fichier:
est converti en:
Exemple 2:
Exemple 3:
la source
Si vous utilisez v4, cela est intégré . Sinon, voici une solution simple et largement applicable . D'autres réponses (et commentaires) sur ce fil ont été très utiles pour créer le code ci-dessous.
Remarques:
a="Hi All"
et ensuite:lcase a
fera la même chose que:a=$( echolcase "Hi All" )
${!1//\'/"'\''"}
au lieu de${!1}
permet à cela de fonctionner même lorsque la chaîne a des guillemets.la source
Pour les versions de Bash antérieures à 4.0, cette version devrait être la plus rapide (car elle ne fork / n'exécute aucune commande):
La réponse de technosaurus avait aussi du potentiel, même si elle fonctionnait correctement pour moi.
la source
Malgré l'âge de cette question et similaire à cette réponse du technosaurus . J'ai eu du mal à trouver une solution portable sur la plupart des plates-formes (que j'utilise) ainsi que sur les anciennes versions de bash. J'ai également été frustré par les tableaux, les fonctions et l'utilisation des impressions, des échos et des fichiers temporaires pour récupérer des variables triviales. Cela fonctionne très bien pour moi jusqu'à présent, je pensais que je partagerais. Mes principaux environnements de test sont:
Style C simple pour une boucle pour parcourir les cordes. Pour la ligne ci-dessous, si vous n'avez jamais rien vu de tel auparavant, c'est là que j'ai appris cela . Dans ce cas, la ligne vérifie si le caractère $ {input: $ i: 1} (minuscule) existe en entrée et si c'est le cas le remplace par le caractère donné $ {ucs: $ j: 1} (majuscule) et le stocke en entrée.
la source
Il s'agit d'une variante beaucoup plus rapide de l'approche de JaredTS486 qui utilise les capacités natives de Bash (y compris les versions Bash <4.0) pour optimiser son approche.
J'ai chronométré 1000 itérations de cette approche pour une petite chaîne (25 caractères) et une chaîne plus grande (445 caractères), à la fois pour les conversions en minuscules et en majuscules. Étant donné que les chaînes de test sont principalement en minuscules, les conversions en minuscules sont généralement plus rapides qu'en majuscules.
J'ai comparé mon approche avec plusieurs autres réponses sur cette page qui sont compatibles avec Bash 3.2. Mon approche est beaucoup plus performante que la plupart des approches documentées ici, et est encore plus rapide que
tr
dans plusieurs cas.Voici les résultats de chronométrage pour 1000 itérations de 25 caractères:
tr
minuscule; 3.81s pour les majusculesRésultats de chronométrage pour 1000 itérations de 445 caractères (composé du poème "Le Robin" de Witter Bynner):
tr
minuscule; 4s pour les majusculesSolution:
L'approche est simple: alors que la chaîne d'entrée contient toutes les lettres majuscules restantes, recherchez la suivante et remplacez toutes les instances de cette lettre par sa variante minuscule. Répétez jusqu'à ce que toutes les lettres majuscules soient remplacées.
Quelques caractéristiques de performance de ma solution:
UCS
etLCS
peut être augmenté de caractères supplémentairesla source
Pour stocker la chaîne transformée dans une variable. À la suite travaillé pour moi -
$SOURCE_NAME
à$TARGET_NAME
la source
Manière simple
la source