Voglio scrivere in maiuscolo solo il primo carattere nella mia stringa con bash.
foo="bar";
//uppercase first character
echo $foo;
dovrebbe stampare "Bar";
Voglio scrivere in maiuscolo solo il primo carattere nella mia stringa con bash.
foo="bar";
//uppercase first character
echo $foo;
dovrebbe stampare "Bar";
Risposte:
foo="$(tr '[:lower:]' '[:upper:]' <<< ${foo:0:1})${foo:1}"
notQuiteCamelin NotQuiteCamel. La tua variante ha l'effetto collaterale o costringe il restante a minuscole, al costo di raddoppiare il numero di sub shell e processi tr.
bash.
Un modo con bash (versione 4+):
foo=bar
echo "${foo^}"
stampe:
Bar
"${foo,}". Per minuscole tutte le lettere, utilizzare "${foo,,}". Per mettere in maiuscolo tutte le lettere, utilizzare "${foo^^}".
${foo~}e ${foo~~}hanno lo stesso effetto di ${foo^}e ${foo^^}. Ma non ho mai visto quell'alternativa menzionata da nessuna parte.
bad substitution
Un modo con sed:
echo "$(echo "$foo" | sed 's/.*/\u&/')"
stampe:
Bar
brew install coreutils gnu-sede segui le istruzioni per usare i comandi senza il prefisso g. Per quello che vale non ho mai voluto eseguire la versione OSX di questi comandi da quando ho ottenuto le versioni GNU.
sedin questo caso avrai bisogno di GNU
sed 's/./\U&/e funzionerà su POSIX sed.
$ foo="bar";
$ foo=`echo ${foo:0:1} | tr '[a-z]' '[A-Z]'`${foo:1}
$ echo $foo
Bar
Ecco il modo "nativo" degli strumenti di testo:
#!/bin/bash
string="abcd"
first=`echo $string|cut -c1|tr [a-z] [A-Z]`
second=`echo $string|cut -c2-`
echo $first$second
tr [:lower:] [:upper:]è una scelta migliore se deve funzionare in una lingua / locale che incorpora lettere che non sono negli intervalli a-zo A-Z.
Utilizzando solo awk
foo="uNcapItalizedstrIng"
echo $foo | awk '{print toupper(substr($0,0,1))tolower(substr($0,2))}'
Può essere fatto anche in bash puro con 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}"
foo = $1ma ottengo solo-bash: foo: command not found
=assegnazioni. Questo è qualcosa che shellcheck.net troverà programmaticamente per te.
=come argomento a un programma (come dovrebbe sapere se someprogram =è in esecuzione someprogramo assegnare a una variabile chiamata someprogram?)
Funziona anche questo ...
FooBar=baz
echo ${FooBar^^${FooBar:0:1}}
=> Baz
FooBar=baz
echo ${FooBar^^${FooBar:1:1}}
=> bAz
FooBar=baz
echo ${FooBar^^${FooBar:2:2}}
=> baZ
E così via.
fonti:
Inroductions / Tutorial:
Per scrivere in maiuscolo solo la prima parola:
foo='one two three'
foo="${foo^}"
echo $foo
O ne due tre
Per scrivere in maiuscolo ogni parola nella variabile:
foo="one two three"
foo=( $foo ) # without quotes
foo="${foo[@]^}"
echo $foo
O NE T wo T hree
(funziona in bash 4+)
foo='one two three'; foo=$(for i in $foo; do echo -n "${i^} "; done) Risoluzione più breve per ogni parola. foo Now is "One Two Three"
Soluzione alternativa e pulita per Linux e OSX, può essere utilizzata anche con variabili bash
python -c "print(\"abc\".capitalize())"
restituisce Abc
Questo ha funzionato per me:
Cerca tutti i file * php nella directory corrente e sostituisci il primo carattere di ciascun nome file con la lettera maiuscola:
ad esempio: test.php => Test.php
for f in *php ; do mv "$f" "$(\sed 's/.*/\u&/' <<< "$f")" ; done
solo per divertimento eccoti qui:
foo="bar";
echo $foo | awk '{$1=toupper(substr($1,0,1))substr($1,2)}1'
# or
echo ${foo^}
# or
echo $foo | head -c 1 | tr [a-z] [A-Z]; echo $foo | tail -c +2
# or
echo ${foo:1} | sed -e 's/^./\B&/'
Non esattamente quello che è stato chiesto, ma piuttosto utile
declare -u foo #When the variable is assigned a value, all lower-case characters are converted to upper-case.
foo=bar
echo $foo
BAR
E il contrario
declare -l foo #When the variable is assigned a value, all upper-case characters are converted to lower-case.
foo=BAR
echo $foo
bar
first-letter-to-lower () {
str=""
space=" "
for i in $@
do
if [ -z $(echo $i | grep "the\|of\|with" ) ]
then
str=$str"$(echo ${i:0:1} | tr '[A-Z]' '[a-z]')${i:1}$space"
else
str=$str${i}$space
fi
done
echo $str
}
first-letter-to-upper-xc () {
v-first-letter-to-upper | xclip -selection clipboard
}
first-letter-to-upper () {
str=""
space=" "
for i in $@
do
if [ -z $(echo $i | grep "the\|of\|with" ) ]
then
str=$str"$(echo ${i:0:1} | tr '[a-z]' '[A-Z]')${i:1}$space"
else
str=$str${i}$space
fi
done
echo $str
}
first-to-lower-xc () {v-first-letter-to-lower | xclip -selection appunti}
Cosa succede se il primo carattere non è una lettera (ma una scheda, uno spazio e una virgoletta doppia evasa)? Faremmo meglio a provarlo fino a quando non troviamo una lettera! Così:
S=' \"ó foo bar\"'
N=0
until [[ ${S:$N:1} =~ [[:alpha:]] ]]; do N=$[$N+1]; done
#F=`echo ${S:$N:1} | tr [:lower:] [:upper:]`
#F=`echo ${S:$N:1} | sed -E -e 's/./\u&/'` #other option
F=`echo ${S:$N:1}
F=`echo ${F} #pure Bash solution to "upper"
echo "$F"${S:(($N+1))} #without garbage
echo '='${S:0:(($N))}"$F"${S:(($N+1))}'=' #garbage preserved
Foo bar
= \"Foo bar=
$[...]). Stai usando molte parentesi inutili. Stai assumendo che la stringa sia composta da caratteri dell'alfabeto latino (che ne dici di lettere accentate o lettere in altri alfabeti?). Hai lavorato moltissimo per rendere utilizzabile questo frammento! (e dal momento che stai usando regex, potresti anche usare regex per trovare la prima lettera, invece di un ciclo).
tr:if [[ $S =~ ^([^[:alpha:]]*)([[:alpha:]].*) ]]; then out=${BASH_REMATCH[1]}${BASH_REMATCH[2]^}; else out=$S; fi; printf '%s\n' "$out"
echo $fooè un esempio di una situazione in cui il parser si aspetta un elenco di parole ; così nel tuo echo ${F}, i contenuti di Fsono suddivisi in stringhe ed espansi glob. Questo è altrettanto vero per l' echo ${S:$N:1}esempio e tutto il resto. Vedi BashPitfalls # 14 .