如何在Bash中将字符串从大写转换为小写?

146

我一直在寻找将字符串从大写转换为小写的方法。所有的搜索结果都显示使用 tr 命令的方法。

tr 命令的问题在于,只有在我使用 echo 语句时才能得到结果。例如:

y="HELLO"
echo $y| tr '[:upper:]' '[:lower:]'

上述代码可以正常运行,结果为'hello',但我需要将结果赋值给一个变量,代码如下:

y="HELLO"
val=$y| tr '[:upper:]' '[:lower:]'
string=$val world

当像上面那样赋值时,结果为空。

附注:我的Bash版本是3.1.17


对于文件:cat file_name | tr '[:upper:]' '[:lower:]' >> lower - mccurcio
我需要使用val=$(echo $y | tr '[:upper:]' '[:lower:]')而不是仅仅使用val=$y| tr '[:upper:]' '[:lower:]' - mikemtnbikes
7个回答

239
如果你正在使用Bash 4,你可以采用以下方法:
x="HELLO"
echo $x  # HELLO

y=${x,,}
echo $y  # hello

z=${y^^}
echo $z  # HELLO

只使用一个 ,^ 来使第一个字母变成 小写大写


2
感谢您的及时回复。当我尝试上述方法时,它显示${y,,}--bad substitution。无论如何,我尝试了另一种方法:y="HI" val = $( tr '[A-Z]' '[a-z]' <<< $y),这对我起作用了。再次感谢。 - raga
10
你的Bash版本太低了,无法支持这些功能。 - kev
8
“,, ^^” 的替换只能在bash 4上使用,而不能在bash 3上使用,因此您需要升级bash或使用tr方法。 - Ian
2
如果返回了坏的替换消息,请同时检查您是否在变量名之前意外地写了“$”(例如${$y,,}而不是${y,,}),这将导致与Bash版本太低时相同的错误(您可以使用“bash --version”命令进行检查)。 - BartekM
5
我一开始有些困惑,因为我执行了 bash --version 命令后显示的是 5.0.3 版本,但后来意识到这是 brew 安装的 bash(位于 /usr/local/bin/bash)。我的脚本头部使用的是系统自带的 bash,即 #!/bin/bash,但版本是 3 :( - combinatorist
显示剩余5条评论

90

实现您的代码的一种方法是:

y="HELLO"
val=$(echo "$y" | tr '[:upper:]' '[:lower:]')
string="$val world"

这里使用 $(...) 记号将命令输出内容捕获到一个变量中。注意在 string 变量周围的引号 -- 必须添加它们以表明 $valworld 是要分配给 string 的单个内容。

如果你有Bash 4.0或更高版本,一种更高效优雅的方法是使用Bash内置的字符串操作:

y="HELLO"
string="${y,,} world"

36
请注意,tr 只能处理纯 ASCII,因此在面对国际字符时,任何基于 tr 的解决方案都会失败。
同样的情况也适用于基于 Bash 4 的 ${x,,} 解决方案。
另一方面,AWK 工具可以正确支持甚至包括 UTF-8 / 多字节输入的情况。
y="HELLO"
val=$(echo "$y" | awk '{print tolower($0)}')
string="$val world"

以下内容由liborw提供。


1
谢谢。使用“tr”选项对我没有起作用。可能是MacOS/BSD的问题。 - TastyWheat

26

使用反引号执行:

 x=`echo "$y" | tr '[:upper:]' '[:lower:]'` 

这将把反引号命令的结果赋值给变量 x。(也就是说,这不仅适用于tr,而且是shell脚本中常见的模式/解决方案。)

您可以使用$(..)代替反引号。有关更多信息,请参见此处


5
非常感谢你的回答。上述方法可行。为了使它更好,我尝试了以下代码:y="HI" val=$(tr '[A-Z]' '[a-z]' <<< $y)对我来说效果很好。再次感谢你的建议。 - raga
1
@raga <<< - 真是太棒了!!! 比起 echo 更加优雅,而且不会过度设计 ☺︎ - msciwoj
1
请记住,在反引号内,\$、双反斜杠和反斜线反引号不会被视为字面量,但在$(..)内部会被视为字面量。这可能是好的或坏的,具体取决于您的用例。http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html第3.4.5节。 - Jeremy

11

我正在使用Ubuntu 14.04 (Trusty Tahr)系统,Bash版本为4.3.11。但是,我仍然没有内置的有趣字符串操作${y,,}

这是我在脚本中用来强制大写的方法:

CAPITALIZED=`echo "${y}" | tr '[a-z]' '[A-Z]'`

你的脚本顶部的shebang行是否指向旧版本的bash? - Tan Wang
不,我只在我的系统上安装了一个版本,所以它指向系统默认的bash。 - BoomShadow
我认为[]是不必要的:https://unix.stackexchange.com/questions/51983/how-to-uppercase-the-command-line-argument#comment801846_344791 - Ciro Santilli OurBigBook.com
1
${y,,} won't work in Ubuntu if you use #!/bin/sh since the default shell is Dash. You must use #!/bin/bash - David Lopez

6
如果您使用declare(旧称:typeset)定义变量,那么在整个变量的使用过程中都可以指定值的大小写。
declare -u FOO=AbCxxx
echo $FOO

输出:

ABCXXX

使用选项-l声明变量,可以将所有大写字母转换为小写字母:

当变量被赋值时,所有大写字母都会被转换成小写字母。大写属性将被禁用。


2
不支持Bash 3.2版本 - Amit Naidu
2
Bash 3.2于2006年10月11日发布(近16年前)。这是在Shellshock(2014年正式被发现之前)之前发布的。 - Peter Mortensen
@Amit Naidu:你使用的是什么系统? - Peter Mortensen

4

在Rody的回答基础上构建, 这对我有用。

y="HELLO"
val=$(echo $y | tr '[:upper:]' '[:lower:]')
string="$val world"

有一个小修改:如果您在变量旁使用下划线,需要将变量名放入 {} 中。

string="${val}_world"

只有下划线吗(这不是反问)?其他标点符号呢,比如逗号? - Peter Mortensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接