Chcę wstawić wielką literę tylko do pierwszego znaku w moim ciągu za pomocą bash.
foo="bar";
//uppercase first character
echo $foo;
powinien wydrukować „Bar”;
Chcę wstawić wielką literę tylko do pierwszego znaku w moim ciągu za pomocą bash.
foo="bar";
//uppercase first character
echo $foo;
powinien wydrukować „Bar”;
Odpowiedzi:
foo="$(tr '[:lower:]' '[:upper:]' <<< ${foo:0:1})${foo:1}"
notQuiteCamelsię NotQuiteCamel. Twój wariant ma efekt uboczny lub zmusza pozostałe do małych liter - kosztem podwojenia liczby podpowłok i procesów tr.
bash.
W jedną stronę z bash (wersja 4+):
foo=bar
echo "${foo^}"
wydruki:
Bar
"${foo,}". Aby wszystkie litery były małe, użyj "${foo,,}". Aby wszystkie litery były wielkie, użyj "${foo^^}".
${foo~}i ${foo~~}mam taki sam efekt jak ${foo^}i ${foo^^}. Ale nigdy nie widziałem tej alternatywy nigdzie wspomnianej.
bad substitution
W jedną stronę z sed:
echo "$(echo "$foo" | sed 's/.*/\u&/')"
Wydruki:
Bar
brew install coreutils gnu-sedi postępuj zgodnie z instrukcjami, aby użyć poleceń bez prefiksu g. Na ile to warte, nigdy nie chciałem uruchamiać wersji tych poleceń dla OSX od czasu otrzymania wersji GNU.
sedw tym przypadku będziesz potrzebować GNU
sed 's/./\U&/i będzie działać na POSIX sed.
$ foo="bar";
$ foo=`echo ${foo:0:1} | tr '[a-z]' '[A-Z]'`${foo:1}
$ echo $foo
Bar
Oto "natywne" narzędzia tekstowe:
#!/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:]jest lepszym wyborem, jeśli musi działać w języku / ustawieniach regionalnych zawierających litery spoza zakresu a-zlub A-Z.
Używanie tylko awk
foo="uNcapItalizedstrIng"
echo $foo | awk '{print toupper(substr($0,0,1))tolower(substr($0,2))}'
Można to zrobić również w czystym bashu z 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 = $1ale dostaję tylko-bash: foo: command not found
=w zadaniach. To jest coś, co shellcheck.net znajdzie dla Ciebie programowo.
=jako argumentu do programu (skąd ma wiedzieć, czy someprogram =działa someprogram, czy przypisać do zmiennej o nazwie someprogram?)
To też działa ...
FooBar=baz
echo ${FooBar^^${FooBar:0:1}}
=> Baz
FooBar=baz
echo ${FooBar^^${FooBar:1:1}}
=> bAz
FooBar=baz
echo ${FooBar^^${FooBar:2:2}}
=> baZ
I tak dalej.
Źródła:
Wprowadzenie / samouczki:
Aby pisać wielką literą tylko pierwsze słowo:
foo='one two three'
foo="${foo^}"
echo $foo
O ne dwa, trzy
Aby zapisać każde słowo w zmiennej wielką literą :
foo="one two three"
foo=( $foo ) # without quotes
foo="${foo[@]^}"
echo $foo
O ne T wo T hree
(działa w bash 4+)
foo='one two three'; foo=$(for i in $foo; do echo -n "${i^} "; done) Mniejsza rozdzielczość dla każdego słowa. foo Now to „One Two Three”
Alternatywne i czyste rozwiązanie zarówno dla Linuksa, jak i OSX, może być również używane ze zmiennymi bash
python -c "print(\"abc\".capitalize())"
zwraca Abc
Ten pracował dla mnie:
Wyszukiwanie wszystkich plików * php w bieżącym katalogu i zamień pierwszy znak każdej nazwy pliku na wielką literę:
np .: test.php => Test.php
for f in *php ; do mv "$f" "$(\sed 's/.*/\u&/' <<< "$f")" ; done
Nie dokładnie to, o co pytano, ale całkiem pomocne
declare -u foo #When the variable is assigned a value, all lower-case characters are converted to upper-case.
foo=bar
echo $foo
BAR
I odwrotnie
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-letter-to-lower-xc () {v-first-letter-to-lower | xclip - schowek wyboru}
Co się stanie, jeśli pierwszy znak nie jest literą (ale tabulatorem, spacją i podwójnym cudzysłowem ze znakiem ucieczki)? Lepiej to przetestujmy , aż znajdziemy list! Więc:
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=
$[...]). Używasz wielu bezużytecznych nawiasów. Zakładasz, że ciąg składa się ze znaków alfabetu łacińskiego (co powiesz na litery akcentowane lub litery z innych alfabetów?). Masz dużo pracy, aby uczynić ten fragment kodu użytecznym! (a ponieważ używasz wyrażenia regularnego, równie dobrze możesz użyć wyrażenia regularnego do znalezienia pierwszej litery zamiast pętli).
tr:if [[ $S =~ ^([^[:alpha:]]*)([[:alpha:]].*) ]]; then out=${BASH_REMATCH[1]}${BASH_REMATCH[2]^}; else out=$S; fi; printf '%s\n' "$out"
echo $foojest to przykład sytuacji, w której parser oczekuje listy słów ; więc w twoim echo ${F}, zawartość Fjest dzielona na łańcuchy i rozszerzana globalnie. Podobnie jest w przypadku echo ${S:$N:1}przykładu i całej reszty. Zobacz BashPitfalls # 14 .