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

ass*_*sin 1158 string bash shell lowercase uppercase

有一种方法可以将字符串转换为小写字符串吗?

例如,如果我有:

a="Hi all"
Run Code Online (Sandbox Code Playgroud)

我想将其转换为:

"hi all"
Run Code Online (Sandbox Code Playgroud)

gho*_*g74 2028

各种方式:

POSIX标准

TR

$ echo "$a" | tr '[:upper:]' '[:lower:]'
hi all
Run Code Online (Sandbox Code Playgroud)

AWK

$ echo "$a" | awk '{print tolower($0)}'
hi all
Run Code Online (Sandbox Code Playgroud)

非POSIX

您可能会遇到以下示例遇到的可移植性问题:

Bash 4.0

$ echo "${a,,}"
hi all
Run Code Online (Sandbox Code Playgroud)

SED

$ echo "$a" | sed -e 's/\(.*\)/\L\1/'
hi all
# this also works:
$ sed -e 's/\(.*\)/\L\1/' <<< "$a"
hi all
Run Code Online (Sandbox Code Playgroud)

Perl的

$ echo "$a" | perl -ne 'print lc'
hi all
Run Code Online (Sandbox Code Playgroud)

巴什

lc(){
    case "$1" in
        [A-Z])
        n=$(printf "%d" "'$1")
        n=$((n+32))
        printf \\$(printf "%o" "$n")
        ;;
        *)
        printf "%s" "$1"
        ;;
    esac
}
word="I Love Bash"
for((i=0;i<${#word};i++))
do
    ch="${word:$i:1}"
    lc "$ch"
done
Run Code Online (Sandbox Code Playgroud)

  • `tr'[:upper:]''[:lower:]'`将使用当前的语言环境来确定大写/小写的等价物,因此它适用于使用带变音标记的字母的语言环境. (175认同)
  • @Adam:`b ="$(echo $ a | tr'[AZ]''[az]')"` (56认同)
  • 请注意,POSIX标准中仅指定了`tr`和`awk`示例. (25认同)
  • 如何将输出转换为新变量?即我想将小写字符串转换为新变量? (10认同)
  • 我错过了什么,或者你的最后一个例子(在Bash中)是否真的做了一些完全不同的事情?它适用于"ABX",但是如果你改为`word ="Hi All",就像其他例子一样,它会返回`ha`,而不是`hi all`.它仅适用于大写字母并跳过已经较低的字母. (9认同)
  • 再次@Adam:Bash4 的 `b="${a,,}"` 比 `b="$(echo ${a,,})"` 更高效。两者都有点不同,如 `a="H W"`(H 和 W 之间有 3 个空格),第一个集合为 `b="h w"`(3 个空格),后一个集合为 `b="h w"`(1 个空格) ) (抱歉,SO 删除了示例中的多个空格) (2认同)
  • 在 Ubuntu 12.10 上,`awk '{print tolower($0)}'` 可以很好地转换依赖于语言环境的字符,但这些字符会失败:`${a,,}` `tr '[:upper:]' '[:lower:]' `. (2认同)
  • `echo "$a"` 很容易失败,例如如果 `a="-n"`。使用 `printf` 是安全的: `result="$(printf "%s" "$a" | tr '[:upper:]' '[:lower:]')"` (2认同)

Pau*_*ce. 415

在Bash 4中:

小写

$ string="A FEW WORDS"
$ echo "${string,}"
a FEW WORDS
$ echo "${string,,}"
a few words
$ echo "${string,,[AEIUO]}"
a FeW WoRDS

$ string="A Few Words"
$ declare -l string
$ string=$string; echo "$string"
a few words
Run Code Online (Sandbox Code Playgroud)

大写

$ string="a few words"
$ echo "${string^}"
A few words
$ echo "${string^^}"
A FEW WORDS
$ echo "${string^^[aeiou]}"
A fEw wOrds

$ string="A Few Words"
$ declare -u string
$ string=$string; echo "$string"
A FEW WORDS
Run Code Online (Sandbox Code Playgroud)

切换(未记录,但可选择在编译时配置)

$ string="A Few Words"
$ echo "${string~~}"
a fEW wORDS
$ string="A FEW WORDS"
$ echo "${string~}"
a FEW WORDS
$ string="a few words"
$ echo "${string~}"
A few words
Run Code Online (Sandbox Code Playgroud)

大写(未记录,但可选择在编译时配置)

$ string="a few words"
$ declare -c string
$ string=$string
$ echo "$string"
A few words
Run Code Online (Sandbox Code Playgroud)

标题案例:

$ string="a few words"
$ string=($string)
$ string="${string[@]^}"
$ echo "$string"
A Few Words

$ declare -c string
$ string=(a few words)
$ echo "${string[@]}"
A Few Words

$ string="a FeW WOrdS"
$ string=${string,,}
$ string=${string~}
$ echo "$string"
A few words
Run Code Online (Sandbox Code Playgroud)

要关闭declare属性,请使用+.例如,declare +c string.这会影响后续分配,而不会影响当前值.

declare选项更改变量的属性,而不是内容.我的示例中的重新分配更新了内容以显示更改.

编辑:

${var~}按照ghostdog74的建议添加"逐字逐句切换"().

编辑:更正了波形符合行为以匹配Bash 4.3.

  • 还有`$ {string~}` (5认同)
  • 相当古怪,"^^"和",,"运算符不适用于非ASCII字符,但"~~"表示...所以`string ="łódź"; echo $ {string ~~}`将返回"ŁÓDŹ",但`echo $ {string ^^}`返回"łóDź".甚至在`LC_ALL = pl_PL.utf-8`中.那是使用bash 4.2.24. (5认同)
  • @HubertKario:Bash维护者已[确认](https://groups.google.com/forum/?fromgroups#!topic/gnu.bash.bug/K4xWT6V7es0)该错误并声明将在下一版本中修复. (4认同)
  • @HubertKario:这很奇怪.在Bash 4.0.33中对我来说也是一样的,在`en_US.UTF-8`中使用相同的字符串.这是一个错误,我已经报告过了. (2认同)

shu*_*lov 120

echo "Hi All" | tr "[:upper:]" "[:lower:]"
Run Code Online (Sandbox Code Playgroud)

  • 为什么需要`[:upper:]`? (6认同)
  • @RichardHansen:对于非ACII角色,`tr`对我不起作用.我确实有正确的语言环境集和生成的语言环境文件.知道我能做错什么吗? (4认同)

Ign*_*ams 76

tr:

a="$(tr [A-Z] [a-z] <<< "$a")"
Run Code Online (Sandbox Code Playgroud)

AWK:

{ print tolower($0) }
Run Code Online (Sandbox Code Playgroud)

sed:

y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
Run Code Online (Sandbox Code Playgroud)

  • +1`a ="$(tr [AZ] [az] <<<"$ a")"`对我来说最简单.我还是初学者...... (2认同)
  • 我强烈推荐`sed`解决方案;我一直在由于某种原因没有`tr`的环境中工作,但是我还没有找到没有`sed`的系统,而且我想这样做的时间很多,我只是做了一些事情否则在sed中可以将命令链接在一起成为一条(长)语句。 (2认同)
  • 应引用括号表达式.在`tr [AZ] [az] A`中,如果设置了由单个字母或*nullgob*组成的文件名,则shell可以执行文件名扩展.`tr"[AZ]""[az]"A`表现正常. (2认同)
  • @CamiloMartin它是一个BusyBox系统,我遇到了这个问题,特别是Synology NASes,但我也在其他几个系统上遇到过它.我最近一直在做很多跨平台的shell脚本,并且要求不需要额外安装它会让事情变得非常棘手!但是我还没有遇到没有`sed`的系统 (2认同)
  • 请注意,几乎所有语言环境中的`tr [AZ] [az]`都不正确.例如,在`en-US`语言环境中,`AZ`实际上是区间'AaBbCcDdEeFfGgHh ... XxYyZ`. (2认同)

net*_*tux 41

我知道这是一个古老的帖子,但我为另一个网站做了这个答案,所以我想我会在这里发布:

UPPER - > lower:使用python:

b=`echo "print '$a'.lower()" | python`
Run Code Online (Sandbox Code Playgroud)

或Ruby:

b=`echo "print '$a'.downcase" | ruby`
Run Code Online (Sandbox Code Playgroud)

或者Perl(可能是我最喜欢的):

b=`perl -e "print lc('$a');"`
Run Code Online (Sandbox Code Playgroud)

或PHP:

b=`php -r "print strtolower('$a');"`
Run Code Online (Sandbox Code Playgroud)

或者awk:

b=`echo "$a" | awk '{ print tolower($1) }'`
Run Code Online (Sandbox Code Playgroud)

或者Sed:

b=`echo "$a" | sed 's/./\L&/g'`
Run Code Online (Sandbox Code Playgroud)

或者Bash 4:

b=${a,,}
Run Code Online (Sandbox Code Playgroud)

或NodeJS,如果你有它(并且有点疯狂......):

b=`echo "console.log('$a'.toLowerCase());" | node`
Run Code Online (Sandbox Code Playgroud)

你也可以使用dd(但我不会!):

b=`echo "$a" | dd  conv=lcase 2> /dev/null`
Run Code Online (Sandbox Code Playgroud)

降低 - > UPPER:

使用python:

b=`echo "print '$a'.upper()" | python`
Run Code Online (Sandbox Code Playgroud)

或Ruby:

b=`echo "print '$a'.upcase" | ruby`
Run Code Online (Sandbox Code Playgroud)

或者Perl(可能是我最喜欢的):

b=`perl -e "print uc('$a');"`
Run Code Online (Sandbox Code Playgroud)

或PHP:

b=`php -r "print strtoupper('$a');"`
Run Code Online (Sandbox Code Playgroud)

或者awk:

b=`echo "$a" | awk '{ print toupper($1) }'`
Run Code Online (Sandbox Code Playgroud)

或者Sed:

b=`echo "$a" | sed 's/./\U&/g'`
Run Code Online (Sandbox Code Playgroud)

或者Bash 4:

b=${a^^}
Run Code Online (Sandbox Code Playgroud)

或NodeJS,如果你有它(并且有点疯狂......):

b=`echo "console.log('$a'.toUpperCase());" | node`
Run Code Online (Sandbox Code Playgroud)

你也可以使用dd(但我不会!):

b=`echo "$a" | dd  conv=ucase 2> /dev/null`
Run Code Online (Sandbox Code Playgroud)

当你说'shell'时,我假设你的意思,bash但如果你可以使用zsh它就像

b=$a:l
Run Code Online (Sandbox Code Playgroud)

小写和

b=$a:u
Run Code Online (Sandbox Code Playgroud)

对于大写.

  • **不要使用!**所有生成脚本的例子都非常脆弱; 如果`a`的值包含单引号,那么您不仅会破坏行为,还会出现严重的安全问题. (5认同)
  • sed命令和bash命令都不适合我. (2认同)

Sco*_*ley 29

在zsh中:

echo $a:u
Run Code Online (Sandbox Code Playgroud)

得爱zsh!

  • 或$ a:l用于小写转换 (4认同)
  • 再添加一个情况:`echo ${(C)a} #Upcase the first char only` (2认同)

dev*_*ull 18

使用GNU sed:

sed 's/.*/\L&/'
Run Code Online (Sandbox Code Playgroud)

例:

$ foo="Some STRIng";
$ foo=$(echo "$foo" | sed 's/.*/\L&/')
$ echo "$foo"
some string
Run Code Online (Sandbox Code Playgroud)


Fin*_*sen 14

对于 Bash 命令行,根据区域设置和国际字母,这可能有效(根据其他人的答案汇总):

\n
$ echo "ABC\xc3\x86\xc3\x98\xc3\x85" | python -c "print(open(0).read().lower())"\nabc\xc3\xa6\xc3\xb8\xc3\xa5\n$ echo "ABC\xc3\x86\xc3\x98\xc3\x85" | sed \'s/./\\L&/g\'\nabc\xc3\xa6\xc3\xb8\xc3\xa5\n$ export a="ABC\xc3\x86\xc3\x98\xc3\x85" | echo "${a,,}"\nabc\xc3\xa6\xc3\xb8\xc3\xa5\n
Run Code Online (Sandbox Code Playgroud)\n

然而这些变体可能不起作用:

\n
$ echo "ABC\xc3\x86\xc3\x98\xc3\x85" | tr "[:upper:]" "[:lower:]"\nabc\xc3\x86\xc3\x98\xc3\x85\n$ echo "ABC\xc3\x86\xc3\x98\xc3\x85" | awk \'{print tolower($1)}\'\nabc\xc3\x86\xc3\x98\xc3\x85\n$ echo "ABC\xc3\x86\xc3\x98\xc3\x85" | perl -ne \'print lc\'\nabc\xc3\x86\xc3\x98\xc3\x85\n$ echo \'ABC\xc3\x86\xc3\x98\xc3\x85\' | dd conv=lcase 2> /dev/null\nabc\xc3\x86\xc3\x98\xc3\x85\n
Run Code Online (Sandbox Code Playgroud)\n

  • 是否‘回显“ABCÆØÅ”| ruby -pe '$_.downcase!'` 工作正常吗? (2认同)

Ale*_*Pes 14

[dev@localhost ~]$ TEST=STRESS2
[dev@localhost ~]$ echo ${TEST,,}
stress2
Run Code Online (Sandbox Code Playgroud)


fed*_*qui 13

Bash 5.1通过L参数转换提供了一种直接的方法来做到这一点:

${var@L}
Run Code Online (Sandbox Code Playgroud)

例如,您可以说:

$ v="heLLo"
$ echo "${v@L}"
hello
Run Code Online (Sandbox Code Playgroud)

您还可以使用大写U

$ v="hello"
$ echo "${v@U}"
HELLO
Run Code Online (Sandbox Code Playgroud)

并将第一个字母大写u

$ v="hello"
$ echo "${v@u}"
Hello
Run Code Online (Sandbox Code Playgroud)

  • 哦奇怪。我想知道为什么他们在“${v^^}”和“${v,,}”已经存在的情况下引入这个。 (8认同)

tec*_*rus 11

对于仅使用内置函数的标准shell(无bashisms):

uppers=ABCDEFGHIJKLMNOPQRSTUVWXYZ
lowers=abcdefghijklmnopqrstuvwxyz

lc(){ #usage: lc "SOME STRING" -> "some string"
    i=0
    while ([ $i -lt ${#1} ]) do
        CUR=${1:$i:1}
        case $uppers in
            *$CUR*)CUR=${uppers%$CUR*};OUTPUT="${OUTPUT}${lowers:${#CUR}:1}";;
            *)OUTPUT="${OUTPUT}$CUR";;
        esac
        i=$((i+1))
    done
    echo "${OUTPUT}"
}
Run Code Online (Sandbox Code Playgroud)

对于大写:

uc(){ #usage: uc "some string" -> "SOME STRING"
    i=0
    while ([ $i -lt ${#1} ]) do
        CUR=${1:$i:1}
        case $lowers in
            *$CUR*)CUR=${lowers%$CUR*};OUTPUT="${OUTPUT}${uppers:${#CUR}:1}";;
            *)OUTPUT="${OUTPUT}$CUR";;
        esac
        i=$((i+1))
    done
    echo "${OUTPUT}"
}
Run Code Online (Sandbox Code Playgroud)

  • 确实; `$ {var:1:1}`的子串是一个Bashism. (2认同)

haw*_*126 11

Pre Bash 4.0

Bash降低字符串的大小写并赋值给变量

VARIABLE=$(echo "$VARIABLE" | tr '[:upper:]' '[:lower:]') 

echo "$VARIABLE"
Run Code Online (Sandbox Code Playgroud)

  • 不需要`echo`和pipe:使用`$(tr'[:upper:]''[:lower:]'<<<"$ VARIABLE")` (4认同)
  • @Tino这里的字符串也不能移植到真正旧版本的Bash; 我相信它是在v3中引入的. (2认同)

c4f*_*t0r 9

在bash 4中,您可以使用排版

例:

A="HELLO WORLD"
typeset -l A=$A
Run Code Online (Sandbox Code Playgroud)


Ger*_*mia 9

bash联机帮助页:

${参数^模式}

${参数^^模式}

${参数,模式}

${参数,,模式}

案例修改此扩展修改参数中字母字符的大小写。该模式被扩展以产生一个模式,就像路径名扩展一样。参数扩展值中的每个字符都会根据模式进行测试,如果与模式匹配,则转换其大小写。该模式不应尝试匹配多个字符。^运算符将匹配模式的小写字母转换为大写;,运算符将匹配的大写字母转换为小写字母。^^,, 扩展会转换扩展值中的每个匹配字符^ 和,扩展仅匹配并转换扩展值中的第一个字符如果省略模式,则将其视为 ? ,它匹配每个字符。如果参数@*,则大小写修改操作依次应用于每个位置参数,并且扩展是结果列表。如果 parameter是下标为@*的数组变量,则依次对数组的每个成员进行大小写修改操作,并扩展为结果列表。


Bik*_*h M 8

你可以试试这个

s="Hello World!" 

echo $s  # Hello World!

a=${s,,}
echo $a  # hello world!

b=${s^^}
echo $b  # HELLO WORLD!
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

参考:http://wiki.workassis.com/shell-script-convert-text-to-lowercase-and-uppercase/


小智 7

正则表达式

我想赞扬我希望分享的命令,但实际情况是我从http://commandlinefu.com获取它以供我自己使用.它的优点是,如果您cd到自己的主文件夹中的任何目录,它将递归地将所有文件和文件夹更改为小写,请谨慎使用.这是一个出色的命令行修复,对于存储在驱动器上的大量专辑特别有用.

find . -depth -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;
Run Code Online (Sandbox Code Playgroud)

您可以在find之后指定一个目录来代替点(.),表示当前目录或完整路径.

我希望这个解决方案证明是有用的,这个命令没有做的一件事是用下划线替换空格 - 哦,或许另一次.


the*_*der 6

转换大小写仅适用于字母。所以,这应该工作得很好。

我专注于将 az 之间的字母从大写转换为小写。任何其他字符都应该按原样打印在标准输出中......

将 az 范围内 path/to/file/filename 中的所有文本转换为 AZ

用于将小写字母转换为大写字母

cat path/to/file/filename | tr 'a-z' 'A-Z'
Run Code Online (Sandbox Code Playgroud)

用于从大写转换为小写

cat path/to/file/filename | tr 'A-Z' 'a-z'
Run Code Online (Sandbox Code Playgroud)

例如,

文档名称:

my name is xyz
Run Code Online (Sandbox Code Playgroud)

转换为:

MY NAME IS XYZ
Run Code Online (Sandbox Code Playgroud)

示例 2:

echo "my name is 123 karthik" | tr 'a-z' 'A-Z'
# Output:
# MY NAME IS 123 KARTHIK
Run Code Online (Sandbox Code Playgroud)

示例 3:

echo "my name is 123 &&^&& #@$#@%%& kAR2~thik" | tr 'a-z' 'A-Z'
# Output:
# MY NAME IS 123 &&^&& #@0@%%& KAR2~THIK
Run Code Online (Sandbox Code Playgroud)


小智 6

简单的方法

echo "Hi all" | awk '{ print tolower($0); }'
Run Code Online (Sandbox Code Playgroud)


Ben*_*ear 6

对于 Bash3.2.+ | 苹果:

read -p 'What is your email? ' email
email=$(echo $email | tr '[:upper:]' '[:lower:]')
email="$email"
echo $email
Run Code Online (Sandbox Code Playgroud)


Gus*_*ves 5

许多使用外部程序的答案,实际上并没有使用Bash.

如果你知道你将有 Bash4 可用,你真的应该使用这个${VAR,,}符号(它既简单又酷)。对于 4 之前的 Bash(例如,我的 Mac 仍然使用 Bash 3.2)。我使用了@ghostdog74 答案的更正版本来创建一个更便携的版本。

您可以调用lowercase 'my STRING'并获得小写版本。我阅读了关于将结果设置为 var 的评论,但这并不是真正可移植的Bash,因为我们不能返回字符串。打印它是最好的解决方案。使用类似var="$(lowercase $str)".

这是如何工作的

其工作方式是获取每个字符的 ASCII 整数表示,printf然后使用adding 32ifupper-to->lowersubtracting 32if lower-to->upper。然后printf再次使用将数字转换回字符。从'A' -to-> 'a'我们有 32 个字符的差异。

使用printf说明:

$ printf "%d\n" "'a"
97
$ printf "%d\n" "'A"
65
Run Code Online (Sandbox Code Playgroud)

97 - 65 = 32

这是带有示例的工作版本。
请注意代码中的注释,因为它们解释了很多内容:

#!/bin/bash

# lowerupper.sh

# Prints the lowercase version of a char
lowercaseChar(){
    case "$1" in
        [A-Z])
            n=$(printf "%d" "'$1")
            n=$((n+32))
            printf \\$(printf "%o" "$n")
            ;;
        *)
            printf "%s" "$1"
            ;;
    esac
}

# Prints the lowercase version of a sequence of strings
lowercase() {
    word="$@"
    for((i=0;i<${#word};i++)); do
        ch="${word:$i:1}"
        lowercaseChar "$ch"
    done
}

# Prints the uppercase version of a char
uppercaseChar(){
    case "$1" in
        [a-z])
            n=$(printf "%d" "'$1")
            n=$((n-32))
            printf \\$(printf "%o" "$n")
            ;;
        *)
            printf "%s" "$1"
            ;;
    esac
}

# Prints the uppercase version of a sequence of strings
uppercase() {
    word="$@"
    for((i=0;i<${#word};i++)); do
        ch="${word:$i:1}"
        uppercaseChar "$ch"
    done
}

# The functions will not add a new line, so use echo or
# append it if you want a new line after printing

# Printing stuff directly
lowercase "I AM the Walrus!"$'\n'
uppercase "I AM the Walrus!"$'\n'

echo "----------"

# Printing a var
str="A StRing WITH mixed sTUFF!"
lowercase "$str"$'\n'
uppercase "$str"$'\n'

echo "----------"

# Not quoting the var should also work, 
# since we use "$@" inside the functions
lowercase $str$'\n'
uppercase $str$'\n'

echo "----------"

# Assigning to a var
myLowerVar="$(lowercase $str)"
myUpperVar="$(uppercase $str)"
echo "myLowerVar: $myLowerVar"
echo "myUpperVar: $myUpperVar"

echo "----------"

# You can even do stuff like
if [[ 'option 2' = "$(lowercase 'OPTION 2')" ]]; then
    echo "Fine! All the same!"
else
    echo "Ops! Not the same!"
fi

exit 0
Run Code Online (Sandbox Code Playgroud)

以及运行后的结果:

$ ./lowerupper.sh 
i am the walrus!
I AM THE WALRUS!
----------
a string with mixed stuff!
A STRING WITH MIXED STUFF!
----------
a string with mixed stuff!
A STRING WITH MIXED STUFF!
----------
myLowerVar: a string with mixed stuff!
myUpperVar: A STRING WITH MIXED STUFF!
----------
Fine! All the same!
Run Code Online (Sandbox Code Playgroud)

这应该只适用于 ASCII 字符

对我来说很好,因为我知道我只会将 ASCII 字符传递给它。
例如,我将它用于一些不区分大小写的 CLI 选项。