Tôi muốn viết hoa chỉ ký tự đầu tiên trong chuỗi của tôi bằng bash.
foo="bar";
//uppercase first character
echo $foo;
nên in "Thanh";
Tôi muốn viết hoa chỉ ký tự đầu tiên trong chuỗi của tôi bằng bash.
foo="bar";
//uppercase first character
echo $foo;
nên in "Thanh";
Câu trả lời:
foo="$(tr '[:lower:]' '[:upper:]' <<< ${foo:0:1})${foo:1}"
notQuiteCamel
thành NotQuiteCamel
. Biến thể của bạn có tác dụng phụ hoặc buộc phần còn lại thành chữ thường - với chi phí nhân đôi số lượng vỏ phụ và quy trình tr.
bash
.
Một cách với bash (phiên bản 4+):
foo=bar
echo "${foo^}"
in:
Bar
"${foo,}"
. Để viết thường tất cả các chữ cái, sử dụng "${foo,,}"
. Để viết hoa tất cả các chữ cái, sử dụng "${foo^^}"
.
${foo~}
và ${foo~~}
có tác dụng tương tự như ${foo^}
và ${foo^^}
. Nhưng tôi không bao giờ thấy sự thay thế được đề cập ở bất cứ đâu.
bad substitution
Một cách với sed
:
echo "$(echo "$foo" | sed 's/.*/\u&/')"
Bản in:
Bar
brew install coreutils gnu-sed
và làm theo hướng dẫn để sử dụng các lệnh mà không cần tiền tố g
. Đối với những gì đáng giá tôi chưa bao giờ muốn chạy phiên bản OSX của các lệnh này kể từ khi có phiên bản GNU.
sed
trong trường hợp này
sed 's/./\U&/
và nó sẽ hoạt động trên POSIX sed.
$ foo="bar";
$ foo=`echo ${foo:0:1} | tr '[a-z]' '[A-Z]'`${foo:1}
$ echo $foo
Bar
Đây là cách công cụ văn bản "bản địa":
#!/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:]
là một lựa chọn tốt hơn nếu nó cần hoạt động bằng ngôn ngữ / ngôn ngữ kết hợp các chữ cái không có trong phạm vi a-z
hoặc A-Z
phạm vi.
Chỉ sử dụng awk
foo="uNcapItalizedstrIng"
echo $foo | awk '{print toupper(substr($0,0,1))tolower(substr($0,2))}'
Nó cũng có thể được thực hiện trong bash thuần với 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 = $1
nhưng tôi chỉ nhận được-bash: foo: command not found
=
bài tập. Đây là thứ mà shellcheck.net sẽ tìm cho bạn theo chương trình.
=
làm đối số cho một chương trình (làm thế nào để biết nếu someprogram =
nó đang chạy someprogram
hay gán cho một biến có tên someprogram
?)
Điều này cũng hoạt động ...
FooBar=baz
echo ${FooBar^^${FooBar:0:1}}
=> Baz
FooBar=baz
echo ${FooBar^^${FooBar:1:1}}
=> bAz
FooBar=baz
echo ${FooBar^^${FooBar:2:2}}
=> baZ
Và như thế.
Nguồn:
Giới thiệu / Hướng dẫn:
Để viết hoa chỉ từ đầu tiên:
foo='one two three'
foo="${foo^}"
echo $foo
Ôi hai ba
Để viết hoa mỗi từ trong biến:
foo="one two three"
foo=( $foo ) # without quotes
foo="${foo[@]^}"
echo $foo
O ne T wo T hree
(hoạt động trong bash 4+)
foo='one two three'; foo=$(for i in $foo; do echo -n "${i^} "; done)
Độ phân giải ngắn hơn cho mỗi từ. foo Bây giờ là "Một Hai Ba"
Giải pháp thay thế và sạch cho cả Linux và OSX, nó cũng có thể được sử dụng với các biến bash
python -c "print(\"abc\".capitalize())"
trả lại Abc
Cái này làm việc cho tôi:
Tìm kiếm tất cả tệp * php trong thư mục hiện tại và thay thế ký tự đầu tiên của mỗi tên tệp thành chữ in hoa:
ví dụ: test.php => Test.php
for f in *php ; do mv "$f" "$(\sed 's/.*/\u&/' <<< "$f")" ; done
Không chính xác những gì được hỏi nhưng khá hữu ích
declare -u foo #When the variable is assigned a value, all lower-case characters are converted to upper-case.
foo=bar
echo $foo
BAR
Và ngược lại
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-low-xc () {v-first-letter-to-low | xclip -selection clipboard}
Điều gì xảy ra nếu ký tự đầu tiên không phải là một chữ cái (mà là một tab, một khoảng trắng và một trích dẫn kép thoát)? Chúng tôi nên kiểm tra nó tốt hơn cho đến khi chúng tôi tìm thấy một lá thư! Vì thế:
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=
$[...]
). Bạn đang sử dụng nhiều dấu ngoặc đơn vô dụng. Bạn đang giả sử rằng chuỗi bao gồm các ký tự từ bảng chữ cái Latinh (làm thế nào về các chữ cái có dấu, hoặc các chữ cái trong các bảng chữ cái khác?). Bạn có rất nhiều công việc để kết xuất đoạn trích này có thể sử dụng được! (và vì bạn đang sử dụng regex, bạn cũng có thể sử dụng regex để tìm chữ cái đầu tiên, thay vì vòng lặp).
tr
:if [[ $S =~ ^([^[:alpha:]]*)([[:alpha:]].*) ]]; then out=${BASH_REMATCH[1]}${BASH_REMATCH[2]^}; else out=$S; fi; printf '%s\n' "$out"
echo $foo
là một ví dụ về tình huống mà trình phân tích cú pháp mong đợi một danh sách các từ ; vì vậy echo ${F}
, trong nội dung của bạn , F
phân chia chuỗi và mở rộng toàn cầu. Điều đó tương tự đúng với echo ${S:$N:1}
ví dụ và tất cả phần còn lại. Xem BashPit thác # 14 .