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

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

例如,如果我有:

a="Hi all"

我想将其转换为:

"hi all"

答案

有多种方式:

POSIX 标准

TR

$ echo "$a" | tr '[:upper:]' '[:lower:]'
hi all

AWK

$ echo "$a" | awk '{print tolower($0)}'
hi all

非 POSIX

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

重击 4.0

$ echo "${a,,}"
hi all

sed

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

佩尔

$ echo "$a" | perl -ne 'print lc'
hi all

重击

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

注意:YMMV 就此。即使使用shopt -u nocasematch;它也对我不起作用(GNU bash 版本 4.2.46 和 4.0.33(具有相同的行为 2.05b.0,但未实现 nocasematch)) shopt -u nocasematch; 。取消设置 nocasematch 会导致 [[“” fooBaR“==” FOObar“]] 奇怪地匹配 [Bz] 内的情况,但 [AZ] 错误地匹配了 [Bz]。 Bash 被双负数(“uncasematch”)弄糊涂了! :-)

在 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

大写

$ 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

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

$ 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

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

$ string="a few words"
$ declare -c string
$ string=$string
$ echo "$string"
A few words

标题案例:

$ 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

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

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

编辑:

ghostdog74所建议,添加了 “按单词切换第一个字符”( ${var~} var〜 ${var~} )。

编辑:更正了波浪号行为,以匹配 Bash 4.3。

echo "Hi All" | tr "[:upper:]" "[:lower:]"

tr

a="$(tr [A-Z] [a-z] <<< "$a")"

AWK

{ print tolower($0) }

sed

y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/

我知道这是一篇过时的文章,但是我在另一个网站上做了这个答案,所以我想把它张贴在这里:

上 -> 下 :使用 python:

b=`echo "print '$a'.lower()" | python`

或 Ruby:

b=`echo "print '$a'.downcase" | ruby`

或 Perl(可能是我的最爱):

b=`perl -e "print lc('$a');"`

或 PHP:

b=`php -r "print strtolower('$a');"`

或 Awk:

b=`echo "$a" | awk '{ print tolower($1) }'`

或 Sed:

b=`echo "$a" | sed 's/./\L&/g'`

或重击 4:

b=${a,,}

或 NodeJS(如果有)(有点发疯...):

b=`echo "console.log('$a'.toLowerCase());" | node`

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

b=`echo "$a" | dd  conv=lcase 2> /dev/null`

下 -> 上

使用 python:

b=`echo "print '$a'.upper()" | python`

或 Ruby:

b=`echo "print '$a'.upcase" | ruby`

或 Perl(可能是我的最爱):

b=`perl -e "print uc('$a');"`

或 PHP:

b=`php -r "print strtoupper('$a');"`

或 Awk:

b=`echo "$a" | awk '{ print toupper($1) }'`

或 Sed:

b=`echo "$a" | sed 's/./\U&/g'`

或重击 4:

b=${a^^}

或 NodeJS(如果有)(有点发疯...):

b=`echo "console.log('$a'.toUpperCase());" | node`

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

b=`echo "$a" | dd  conv=ucase 2> /dev/null`

另外,当您说 “shell” 时,我假设您的意思是bash但是如果可以使用zsh它就像

b=$a:l

小写字母和

b=$a:u

大写。

在 zsh 中:

echo $a:u

一定爱 zsh!

使用 GNU sed

sed 's/.*/\L&/'

例:

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

对于仅使用内置函数的标准外壳程序(没有 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}"
}

对于大写:

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}"
}

前 Bash 4.0

Bash 减小字符串的大小写并分配给变量

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

echo "$VARIABLE"

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

例:

A="HELLO WORLD"
typeset -l A=$A