Bien qu'elle soit plus complexe que la réponse la mieux notée, celle-ci fait exactement cela: «premier caractère majuscule dans une variable». La réponse la mieux notée n'a pas ces résultats. On dirait que les réponses simples sont mieux votées que les bonnes?
Krzysztof Jabłoński
15
@ KrzysztofJabłoński: En fait, la "réponse la mieux notée" ci-dessous produira les mêmes résultats que cette réponse sous Bash 4. Cette réponse a la surcharge d'appeler un sous-shell (un autre shell), la surcharge d'appeler l'utilitaire 'tr' (un autre processus , pas Bash), la surcharge de l'utilisation d'un here-doc / string (création de fichier temporaire) et il utilise deux substitutions par rapport à la réponse la mieux notée. Si vous devez absolument écrire du code hérité, envisagez d'utiliser une fonction au lieu d'un sous-shell.
Steve
2
Cette réponse suppose que l'entrée est entièrement en minuscules. Cette variante n'a pas d'hypothèses: $ (tr '[: lower:]' '[: upper:]' <<< $ {foo: 0: 1}) $ (tr '[: upper:]' '[: lower: ] '<<< $ {foo: 1})
Itai Hanski
5
@ItaiHanski L'OP n'a pas précisé ce qui devrait arriver aux caractères restants, seulement le premier. Supposé qu'ils voulaient changer notQuiteCamelen NotQuiteCamel. Votre variante a pour effet secondaire de forcer le reste en minuscules - au prix de doubler le nombre de sous-coquilles et de processus tr.
Jesse Chisholm
3
@DanieleOrlando, c'est vrai, mais cette question n'a pas de balises autres que bash.
@CMCDragonkai: Pour mettre en minuscule la première lettre, utilisez "${foo,}". Pour mettre toutes les lettres en minuscules, utilisez "${foo,,}". Pour mettre toutes les lettres en majuscules, utilisez "${foo^^}".
Steve
1
J'ai accidentellement remarqué cela ${foo~}et ${foo~~}j'ai le même effet que ${foo^}et ${foo^^}. Mais je n'ai jamais vu cette alternative mentionnée nulle part.
mivk le
5
cela ne semble pas fonctionner sur les Mac. obtenir l'erreur suivante:bad substitution
Toland Hon
1
@TolandHon: Comme vous l'avez probablement déjà fait, vous devrez passer à la version 4.x, ou essayer une autre solution si cette machine ne peut pas être mise à niveau pour une raison quelconque.
ne fonctionne pas sur MacOS10 Lion sed, soupir, le \ u se développe en u au lieu d'être un opérateur.
vwvan
2
@vwvan brew install coreutils gnu-sedet suivez les instructions pour utiliser les commandes sans le préfixe g. Pour ce que ça vaut, je n'ai jamais voulu exécuter la version OSX de ces commandes depuis l'obtention des versions GNU.
Dean
@vwvan: Oui, désolé, vous aurez besoin de GNU seddans ce cas
Steve
2
@Dean: FWIW, je n'ai jamais voulu exécuter OSX :-)
Steve
5
Changez-le simplement en sed 's/./\U&/et cela fonctionnera sur POSIX sed.
enfin quelque chose qui fonctionne avec une variable et sur Mac! Je vous remercie!
OZZIE
4
@DanieleOrlando, pas aussi portable qu'on pourrait l'espérer. tr [:lower:] [:upper:]est un meilleur choix s'il doit fonctionner dans une langue / des paramètres régionaux incorporant des lettres qui ne sont pas dans les plages a-zou A-Z.
Cela peut également être fait en pure bash avec bash-3.2:
# First, get the first character.
fl=${foo:0:1}# Safety check: it must be a letter :).if[[ ${fl}==[a-z]]];then# Now, obtain its octal value using printf (builtin).
ord=$(printf '%o'"'${fl}")# Fun fact: [a-z] maps onto 0141..0172. [A-Z] is 0101..0132.# We can use decimal '- 40' to get the expected result!
ord=$(( ord -40))# Finally, map the new value back to a character.
fl=$(printf '%b''\'${ord})
fi
echo "${fl}${foo:1}"
comment définir foo? J'ai essayé foo = $1mais je ne reçois que-bash: foo: command not found
OZZIE
1
@OZZIE, pas d'espace autour des =affectations. C'est quelque chose que shellcheck.net trouvera pour vous par programme.
Charles Duffy
J'oublie toujours ça à propos des scripts shell ... seul langage où un espace (avant / après) compte ... soupir (python vaut au moins 4 si je me souviens bien)
OZZIE
@OZZIE, ça doit avoir de l'importance, car si cela n'avait pas d'importance, vous ne pourriez pas passer =en argument à un programme (comment est-il censé savoir s'il someprogram =est en cours d'exécution someprogram, ou qu'il est assigné à une variable nommée someprogram?)
foo='one two three'; foo=$(for i in $foo; do echo -n "${i^} "; done) Résolution plus courte pour chaque mot. foo Now est "One Two Three"
vr286
Comment puis-je mettre les 3 ou 4 premières lettres en majuscules? Comme pqrs-123-v1 à PQRS-123-v1 ? Ou vous pouvez dire, toutes les lettres avant le premier trait d'union ...
Vicky Dev
2
Solution alternative et propre pour Linux et OSX, elle peut également être utilisée avec des variables bash
Que faire si le premier caractère n'est pas une lettre (mais une tabulation, un espace et un guillemet double échappé)? Nous ferions mieux de le tester jusqu'à ce que nous trouvions une lettre! Alors:
Veuillez écrire un code plus propre! il vous manque des citations partout. Vous utilisez une syntaxe obsolète (backticks); vous utilisez une syntaxe désuète ( $[...]). Vous utilisez beaucoup de parenthèses inutiles. Vous supposez que la chaîne se compose de caractères de l'alphabet latin (qu'en est-il des lettres accentuées ou des lettres d'autres alphabets?). Vous avez beaucoup de travail pour rendre cet extrait utilisable! (et puisque vous utilisez regex, vous pouvez aussi bien utiliser l'expression régulière pour trouver la première lettre, au lieu d'une boucle).
gniourf_gniourf
6
Je crois que vous avez tort. C'est le commentaire obligatoire qui accompagne le vote défavorable, expliquant tous les mauvais modèles et les idées fausses de la réponse. S'il vous plaît, apprenez de vos erreurs (et avant cela, essayez de les comprendre) au lieu d'être têtu. Être un bon garçon est également incompatible avec la diffusion de mauvaises pratiques.
gniourf_gniourf
1
Ou, si vous utilisez Bash ≥4, vous n'avez pas besoin de tr:if [[ $S =~ ^([^[:alpha:]]*)([[:alpha:]].*) ]]; then out=${BASH_REMATCH[1]}${BASH_REMATCH[2]^}; else out=$S; fi; printf '%s\n' "$out"
gniourf_gniourf
5
Ce code est toujours mal rompu. Il utilise toujours des backticks au lieu de la syntaxe de substitution moderne; il a toujours des citations incomparables; il y a encore des citations manquantes là où elles importent réellement ; etc. Essayez de mettre des caractères glob dans vos données de test, si vous ne pensez pas que ces guillemets manquants font une différence, et corrigez les problèmes que shellcheck.net trouve jusqu'à ce que ce code soit clair .
Charles Duffy
2
Quant au langage que vous avez cité sur unix.stackexchange.com/questions/68694/… , ce qui vous manque, c'est qu'il echo $foos'agit d'un exemple de situation où l'analyseur attend une liste de mots ; Ainsi, dans votre echo ${F}, le contenu de Fest divisé en chaîne et étendu globalement. C'est également vrai pour l' echo ${S:$N:1}exemple et tout le reste. Voir BashPitfalls # 14 .
Réponses:
la source
notQuiteCamel
enNotQuiteCamel
. Votre variante a pour effet secondaire de forcer le reste en minuscules - au prix de doubler le nombre de sous-coquilles et de processus tr.bash
.Aller simple avec bash (version 4+):
imprime:
la source
"${foo,}"
. Pour mettre toutes les lettres en minuscules, utilisez"${foo,,}"
. Pour mettre toutes les lettres en majuscules, utilisez"${foo^^}"
.${foo~}
et${foo~~}
j'ai le même effet que${foo^}
et${foo^^}
. Mais je n'ai jamais vu cette alternative mentionnée nulle part.bad substitution
Aller simple avec
sed
:Impressions:
la source
brew install coreutils gnu-sed
et suivez les instructions pour utiliser les commandes sans le préfixeg
. Pour ce que ça vaut, je n'ai jamais voulu exécuter la version OSX de ces commandes depuis l'obtention des versions GNU.sed
dans ce cassed 's/./\U&/
et cela fonctionnera sur POSIX sed.la source
Voici la méthode des outils de texte "natifs":
la source
tr [:lower:] [:upper:]
est un meilleur choix s'il doit fonctionner dans une langue / des paramètres régionaux incorporant des lettres qui ne sont pas dans les plagesa-z
ouA-Z
.Utiliser awk uniquement
la source
Cela peut également être fait en pure bash avec bash-3.2:
la source
foo = $1
mais je ne reçois que-bash: foo: command not found
=
affectations. C'est quelque chose que shellcheck.net trouvera pour vous par programme.=
en argument à un programme (comment est-il censé savoir s'ilsomeprogram =
est en cours d'exécutionsomeprogram
, ou qu'il est assigné à une variable nomméesomeprogram
?)Cela fonctionne aussi ...
Etc.
Sources:
Inroductions / Tutoriels:
la source
Pour mettre en majuscule uniquement le premier mot:
Pour mettre en majuscule chaque mot de la variable:
(fonctionne en bash 4+)
la source
foo='one two three'; foo=$(for i in $foo; do echo -n "${i^} "; done)
Résolution plus courte pour chaque mot. foo Now est "One Two Three"Solution alternative et propre pour Linux et OSX, elle peut également être utilisée avec des variables bash
renvoie Abc
la source
Celui-ci a fonctionné pour moi:
Recherche de tous les fichiers * php dans le répertoire courant, et remplacez le premier caractère de chaque nom de fichier par une majuscule:
par exemple: test.php => Test.php
la source
juste pour le plaisir vous voilà:
la source
Pas exactement ce qui a été demandé mais assez utile
Et le contraire
la source
first-letter-to-lower-xc () {v-first-letter-to-lower | presse-papiers de sélection xclip}
la source
Que faire si le premier caractère n'est pas une lettre (mais une tabulation, un espace et un guillemet double échappé)? Nous ferions mieux de le tester jusqu'à ce que nous trouvions une lettre! Alors:
la source
$[...]
). Vous utilisez beaucoup de parenthèses inutiles. Vous supposez que la chaîne se compose de caractères de l'alphabet latin (qu'en est-il des lettres accentuées ou des lettres d'autres alphabets?). Vous avez beaucoup de travail pour rendre cet extrait utilisable! (et puisque vous utilisez regex, vous pouvez aussi bien utiliser l'expression régulière pour trouver la première lettre, au lieu d'une boucle).tr
:if [[ $S =~ ^([^[:alpha:]]*)([[:alpha:]].*) ]]; then out=${BASH_REMATCH[1]}${BASH_REMATCH[2]^}; else out=$S; fi; printf '%s\n' "$out"
echo $foo
s'agit d'un exemple de situation où l'analyseur attend une liste de mots ; Ainsi, dans votreecho ${F}
, le contenu deF
est divisé en chaîne et étendu globalement. C'est également vrai pour l'echo ${S:$N:1}
exemple et tout le reste. Voir BashPitfalls # 14 .