uppercase first character in a variable with bash
我只想用bash将字符串中的第一个字符大写。
1 2 3 4 5
| foo="bar";
//uppercase first character
echo $foo; |
应打印"条形图";
- 这并不是一个完全重复的问题,但是在bash shell脚本中将字符串转换为小写中描述的许多技术也可以应用于这个问题。
使用bash的单向(版本4+):
印刷品:
- 有什么相反的吗?
- @cmcdragonkai:要小写第一个字母,请使用"${foo,}"。要使所有字母都小写,请使用"${foo,,}"。要将所有字母都大写,请使用"${foo^^}"。
- 这对${foo:?}有什么作用?
- @A-B-B:我不确定你的确切意思,但是如果你想替换foo,你可能需要分配另一个变量。
- 很好,也适用于UTF-8
- 这只会将多单词字符串中第一个单词的第一个字母大写。不是完整的解决方案。
- 我不小心注意到,${foo~}和${foo~~}与${foo^}和${foo^^}具有相同的效果。但我从来没有看到任何地方提到过这种替代方案。
1
| foo="$(tr '[:lower:]' '[:upper:]' <<< ${foo:0:1})${foo:1}" |
- 尽管比最佳答案更复杂,但这个答案确实做到了:"变量中的大写第一个字符"。得分最高的答案没有这样的结果。看起来简单的答案比正确的答案更容易被否决?
- @ KrzysztofJab?奥斯卡:事实上,下面的"最佳答案"将产生与bash4下的答案相同的结果。这个答案有调用子shell(另一个shell)的开销,调用";t";实用程序(另一个进程,而不是bash)的开销,使用here-doc/string(临时文件创建)的开销,与得分最高的answe's-one相比,它使用了两个替换。如果必须编写遗留代码,请考虑使用函数而不是子外壳
- 这个答案假设输入都是小写的。此变量没有假设:$(tr'[:lower:]""[:upper:]"<
- @伊泰汉斯基的操作没有指定应该发生在其余字符,只有第一个。假设他们想将notquitecamelintonotquitecamel您的变体有副作用,或者将剩余的部分强制为小写-代价是将子shell和tr进程的数量加倍
- @Jessechisholm是真的-我的剧本不是对骆驼的友好,而是故意的。
- 您使用了很多bashism,比如<<<和字符串范围,这对于可移植脚本来说不是一件好事。
- 仅适用于ASCI
- @Daniel奥兰多,对,但是这个问题除了bash之外没有其他标签
- @Bell,这取决于本地平台的tr实现是否支持多字节。GNU One不是,但是BSD、Solaris和MacOStrimplementations are fine
单路sed:
1
| echo"$(echo"$foo" | sed 's/.*/\u&/')" |
印刷品:
- 不适用于Macos10 Lion-Sed,叹息,该u扩展到u而不是作为运算符
- @vwvanbrew install coreutils gnu-sed并按照说明使用不带前缀的命令g。值得一提的是,自从获得GNU版本以来,我从来就不想运行这些命令的OSX版本。
- @是的,对不起,您需要GNUsedin this instanc
- @迪安:FWIW,我从来没有想过运行OSX:
- 只需将其更改为sed's&47;&47;u&;&47;,它将在posix-sed上工作
1 2 3 4
| $ foo="bar";
$ foo=`echo ${foo:0:1} | tr '[a-z]' '[A-Z]'`${foo:1}
$ echo $foo
Bar |
以下是"本机"文本工具的方法:
1 2 3 4 5 6
| #!/bin/bash
string="abcd"
first=`echo $string|cut -c1|tr [a-z] [A-Z]`
second=`echo $string|cut -c2-`
echo $first$second |
- 最后是一些与变量和mac一起工作的东西!谢谢你
- @丹尼尔奥兰多,不像人们希望的那样轻便。tr[:lower:][:upper:]是一个更好的选择,如果它需要在语言/区域设置中工作,合并不在a-z中的字母
- @查尔斯达菲是的,你的观点应该是安苏的一部分。n
仅使用AWK
1 2
| foo="uNcapItalizedstrIng"
echo $foo | awk '{print toupper(substr($0,0,1))tolower(substr($0,2))}' |
它也可以用bash-3.2在纯bash中完成:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| # 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}" |
- 不适用于非ASCII字母,如&243;
- 如何定义foo?我试过了foo=$1但是我只得到了-bash:foo:command not found
- @Ozzie,assignments中的=周围没有空格。这是shellcheck.net为您提供的编程工具
- 我总是忘记那些关于shell脚本的事。只有一个空格(前后)重要的语言…叹息(如果我没记错的话,Python至少4岁
- @Ozzie,这很重要,因为如果它不重要,您就不能将=作为参数传递给程序(how is it should to know ifsomeprogram=is runningsomeprogram->code>,or assigning to a variable namedsomeprogram->code>?
这也行…
1 2 3 4 5
| FooBar=baz
echo ${FooBar^^${FooBar:0:1}}
=> Baz |
1 2 3 4 5
| FooBar=baz
echo ${FooBar^^${FooBar:1:1}}
=> bAz |
1 2 3 4 5
| FooBar=baz
echo ${FooBar^^${FooBar:2:2}}
=> baZ |
等等。
资料来源:
- bash手册:shell参数扩展
- 完整bash指南:参数
- bash hacker的wiki参数扩展
简介/教程:
- 电子商务:8.转换为大小写,反之亦然
- opensource.com:bash中参数扩展的介绍
第一个字符为大写,所有其他小写字母:
1 2
| declare -c foo="bar"
echo"$foo" |
或
1 2
| declare -c foo="bar"
echo"$foo" |
输出:
为了你的情况
1 2 3 4 5
| a='one two three'
a="${a^}"
printf '%s
'"$a"
# One two three |
对于每个单词,首字母大写
1 2 3 4 5 6 7 8 9
| a='one two three'
b=( $a ) # $a without quotes
for word in"${b[@]}"; do
c+=("${word^}" )
done
a="${c[*]}"
printf '%s
'"$a"
# One Two Three |
- foo='one two three'; foo=$(for i in $foo; do echo -n"${i^}"; done)每个字的分辨率都较短。foo现在是"一二三"
这个对我有用:
在当前目录中搜索所有*php文件,并将每个文件名的第一个字符替换为大写字母:
例如:test.php=>test.php
1
| for f in *php ; do mv"$f""$(\sed 's/.*/\u&/' <<<"$f")" ; done |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| 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
} |
第一个字母到下-xc()。{v-first-letter-to-lower xclip-选择剪贴板}
如果第一个字符不是字母(而是制表符、空格和转义双引号),该怎么办?我们最好先测试一下,直到找到一封信!所以:
1 2 3 4 5 6 7 8 9 10 11 12
| 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= |
- 请写清洁代码!到处都是你的名言。您使用的是过时的语法(backticks);您使用的是过时的语法($[...])。你用了很多没用的括号。您假设字符串由拉丁字母表中的字符组成(重音字母或其他字母表中的字母如何?)。您有大量工作可以使此代码段可用!(既然您使用的是regex,那么您也可以使用regex来查找第一个字母,而不是循环)。
- 非常,非常悲伤。这是一种具有唯一的破坏意图的评论。没有人有枪在他头上参加一个问答网站。人们都是志愿者!这是一种错误的姿势,有助于打倒斯塔克沃夫社区中的好人所做的好事。
- 我认为你错了。这是强制性的评论,伴随着投反对票,解释了所有错误的模式和对答案的误解。请从你的错误中吸取教训(在那之前,试着去理解它们),而不是固执己见。做一个好朋友也与传播坏习惯不相容。
- 最好写为:if [[ $S =~ ^([^[:alpha:]]*)([[:alpha:]])(.*) ]]; then out=${BASH_REMATCH[1]}$(tr '[[:lower:]]' '[[:upper:]]' <<<"${BASH_REMATCH[2]}")${BASH_REMATCH[3]}; else out=$S; fi; printf '%s
'"$out"。
- 或者,如果使用bash≥4,则不需要tr:if [[ $S =~ ^([^[:alpha:]]*)([[:alpha:]].*) ]]; then out=${BASH_REMATCH[1]}${BASH_REMATCH[2]^}; else out=$S; fi; printf '%s
'"$out"。
- 代码不仅与功能部分有关。代码也是一种表达方式。如果有人不同意代码的编写方式,那该怎么办!做得更好!除了N=$($N+1)处的括号外,上述代码没有任何错误。关于双引号的东西,如${S:$N:1},请检查:unix.stackexchange.com/questions/68694/&hellip;:简而言之,每当需要单词列表或模式时,都需要双引号。每当需要原始字符串时,它们都是可选的。
- 您的bash>4解决方案实际上是"更好"。这绝对不是冒犯。祝贺你。你刚刚提高了人类的能力!
- 关于主题的更多信息:"当"二进制运算符"=~"可用时,将变量扩展放在左侧不加引号是完全安全的,但您需要知道,变量扩展将发生在右侧。"stackoverflow.com/a/18710850/559742
- 答案更新为上面的"提示"。
- 这个代码仍然严重损坏。它仍然使用反勾号而不是现代替换语法;它仍然有不匹配的引号;它在事实上重要的地方仍然有缺少的引号;等等。如果您不相信缺少的引号会产生影响,请尝试在测试数据中放入一些空格包围的glob字符,并修复shellcheck.net fin问题。直到这个代码被清除。
- 至于您从unix.stackexchange.com/questions/68694/&hellip;引用的语言,您会错过的是echo $foo是一个示例,解析器需要一个单词列表;因此在echo ${F}中,F的内容是字符串拆分和全局扩展的。对于echo ${S:$N:1}示例和其他所有示例,这也是同样的道理。见bashpitfalls 14。
- (它仍然使用不推荐使用的语法。N=$[$N+1]不仅仅是一个没有任何功能影响的风格选择:它实际上比取代它的posix标准化N=$((N+1))语法更不可移植,因为它是20世纪70年代Bourne的一个坚持,没有加入到90年代的posix标准中,也不能保证出现在现代基于posix的shell中。