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

How to convert a string to lower case in Bash?

bash中是否有将字符串转换为小写字符串的方法?

例如,如果我有:

1
a="Hi all"

我想把它转换成:

1
"hi all"


在各种不同的方法是: </P > POSIX标准 TR

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

老鹰

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

非POSIX

你可以用下面的问题为portability运行的例子: </P > Bash 4.0

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

SED

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

Perl

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

猛击

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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是这一个。我们的工作不是为T(GNU的bash版本4.2.46和4.0.33(和行为是不一样的,但2.05b.0 nocasematch implemented)甚至shopt -u nocasematch;)与使用。这unsetting nocasematch causes"foobar"[ [ ] ] = ="foobar",但在今天的比赛好吗weirdly [ B ] incorrectly匹配Z是由[ ] A到Z。在混乱的bash由双负("unsetting nocasematch")!!!!!!!::::) </P >


在bash 4: </P >

对lowercase </P >

1
2
3
4
5
6
7
8
9
10
11
12
$ 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

对uppercase </P >

1
2
3
4
5
6
7
8
9
10
11
12
$ 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

toggle(undocumented optionally可配置的时间,但在compile) </P >

1
2
3
4
5
6
7
8
9
$ 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

capitalize(undocumented optionally可配置的时间,但在compile) </P >

1
2
3
4
5
$ string="a few words"
$ declare -c string
$ string=$string
$ echo"$string"
A few words

案例:title </P >

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ 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转弯开关+属性时,使用。for example,declare +c string。这不是affects后assignments和电流值。 </P >

declare选项的属性变化的变量,而不是内容。在我的例子reassignments更新的内容到表演的依据。 </P >

编辑: </P >

补充说,"toggle第一字符中的话:"(${var~})作为suggested ghostdog74主编。 </P >

编辑:corrected Tilde行为对比赛的bash 4.3。 </P >


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


TR:

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

老鹰:

1
{ print tolower($0) }

对话:

1
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/


我知道这是一篇老掉牙的文章,但我为另一个网站做了这个回答,所以我想我会把它贴在这里:

上>下:使用Python:

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

或露比:

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

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

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

或PHP:

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

或AWK:

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

或SED:

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

或BASH 4:

1
b=${a,,}

或者点头,如果你有(而且有点疯…):

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

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

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

下>上:

使用Python:

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

或露比:

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

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

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

或PHP:

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

或AWK:

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

或SED:

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

或BASH 4:

1
b=${a^^}

或者点头,如果你有(而且有点疯…):

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

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

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

另外,当你说"shell"时,我假设你的意思是bash,但是如果你能使用zsh,那么就很容易

1
b=$a:l

小写和

1
b=$a:u

对于大写字母。


在zsh: </P >

1
echo $a:u

zsh得爱!!!!!!! </P >


使用GNU sed: </P >

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

实例: </P >

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

Bash 4.0预 </P >

Bash的情况下一个字符串的指针变量和拨款 </P >

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

echo"$VARIABLE"


用一个标准的壳(不bashisms)使用的只builtins: </P >

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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}"
}

在案例和方法: </P >

1
2
3
4
5
6
7
8
9
10
11
12
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}"
}


4你可以使用在bash的排版 </P >

实例: </P >

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

正则表达式

我明天会把信用状的命令,但我对真理的第一股是我从我自己使用它的方法obtained http:/ / commandlinefu.com。它有优势的,如果你在你的自己的cd到任何目录的文件夹,它将在这家的变化下对文件和folders请小心使用递归的情况下与。。。。。。。它是一个命令行右,右离合器尤其有用的方法和所存储的那些multitudes albums你要你的驱动。 </P >

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

你可以在一个地方specify Directory的点(。),售后服务的全电流或denotes find目录路径。 </P >

我希望这个解决方案proves有用的命令也不做这一件事情是replace函数空间与时间:或许家境富裕,另一underscores哦。。。。。。。 </P >


你可以试试这个

1
2
3
4
5
6
7
8
9
s="Hello World!"

echo $s  # Hello World!

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

b=${s^^}
echo $b  # HELLO WORLD!

enter image description here

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


尽管这个问题有多老,而且与Technosaurus的回答类似。我很难找到一个可以在大多数平台(我使用的)和旧版本的bash之间移植的解决方案。我也对数组、函数和使用打印、echo和临时文件来检索琐碎变量感到沮丧。到目前为止,这对我很有效,我想我会分享。我的主要测试环境是:

  • GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
  • GNU bash, version 3.2.57(1)-release (sparc-sun-solaris2.10)
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    lcs="abcdefghijklmnopqrstuvwxyz"
    ucs="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    input="Change Me To All Capitals"
    for (( i=0; i<"${#input}"; i++ )) ; do :
        for (( j=0; j<"${#lcs}"; j++ )) ; do :
            if [["${input:$i:1}" =="${lcs:$j:1}" ]] ; then
                input="${input/${input:$i:1}/${ucs:$j:1}}"
            fi
        done
    done

    循环迭代字符串的简单C样式。如果你以前没见过这样的东西这就是我学到的。在这种情况下,该行检查输入中是否存在char$input:$i:1(小写),如果存在,则将其替换为给定的char$ucs:$j:1(大写),并将其存储回输入。

    1
    input="${input/${input:$i:1}/${ucs:$j:1}}"


    如果使用V4,这是baked插件。如果不是,这里是一个简单的,widely适用的解决方案。(和其他解答的评论)这是有helpful线程的代码在creating下面。 </P >

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # Like echo, but converts to lowercase
    echolcase () {
        tr [:upper:] [:lower:] <<<"${*}"
    }

    # Takes one arg by reference (var name) and makes it lowercase
    lcase () {
        eval"${1}"=\'$(echo ${!1//\'/"'\''
    <p><center>[wp_ad_camp_3]</center></p><hr><P>许多答案使用外部程序,而不是真正使用<wyn>bash</wyn>。</P><P>如果您知道可以使用bash4,那么您就应该使用<wyn>${VAR,,}</wyn>表示法(它既简单又酷)。对于4之前的bash(例如,我的Mac仍然使用bash 3.2)。我用@ghostdog74的答案的正确版本创建了一个更便携的版本。</P><P>你可以打电话给<wyn>lowercase 'my STRING'</wyn>,得到一个小写版本。我读过有关将结果设置为var的注释,但在<wyn>bash</wyn>中这并不是真正可移植的,因为我们不能返回字符串。打印是最好的解决方案。很容易用像<wyn>var="
    $(lowercase $str)"</wyn>这样的东西捕捉。</P><P>如何工作</P><P>其工作方式是使用<wyn>printf</wyn>获取每个字符的ASCII整数表示,然后使用<wyn>upper-to->lower</wyn>获取<wyn>adding 32</wyn>,如果使用<wyn>lower-to->upper</wyn>获取<wyn>subtracting 32</wyn>。然后再次使用<wyn>printf</wyn>将数字转换回char。从<wyn>'A' -to-> 'a'</wyn>我们有32个字符的差异。</P><P>用<wyn>printf</wyn>解释:</P>[cc lang="bash"]$ printf"%d
    ""'a"
    97
    $ printf"%d
    ""'
    A"
    65

    97 - 65 = 32

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

    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    #!/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!"$'
    '

    uppercase"I AM the Walrus!"$'
    '


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

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

    uppercase"$str"$'
    '


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

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

    uppercase $str$'
    '


    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

    运行后的结果是:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $ ./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!

    但这只适用于ASCII字符。

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


    For Bash versions earlier than 4.0, this version should be fastest (as it doesn't fork/exec any commands):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    function string.monolithic.tolower
    {
       local __word=$1
       local __len=${#__word}
       local __char
       local __octal
       local __decimal
       local __result

       for (( i=0; i<__len; i++ ))
       do
          __char=${__word:$i:1}
          case"$__char" in
             [A-Z] )
                printf -v __decimal '%d'"'$__char"
                printf -v __octal '%03o' $(( $__decimal ^ 0x20 ))
                printf -v __char \\$__octal
                ;;
          esac
          __result+="$__char"
       done
       REPLY="$__result"
    }

    technosaurus的答案,尽管它有潜力带来的运行方法,列出了这份蜂蜜。 </P >


    如果您喜欢python,并且可以选择安装一个新的python包,那么您可以尝试使用这个python实用程序。

    1
    2
    3
    4
    # install pythonp
    $ pip install pythonp

    $ echo $a | pythonp"l.lower()"

    转换大小写只对字母进行。所以,这应该是干净利落的。

    我的重点是将字母从大写字母转换为小写字母。任何其他字符都应该在stdout中打印,因为它是…

    将a-z范围内path/to/file/filename中的所有文本转换为a-z

    用于将小写转换为大写

    1
    cat path/to/file/filename | tr 'a-z' 'A-Z'

    用于从大写转换为小写

    1
    cat path/to/file/filename | tr 'a-z' 'A-Z'

    例如,

    文件名:

    1
    my name is xyz

    转换为:

    1
    my name is xyz

    例2:

    1
    2
    3
    echo"my name is 123 karthik" | tr 'a-z' 'A-Z'
    # Output:
    # MY NAME IS 123 KARTHIK

    例3:

    1
    2
    3
    echo"my name is 123 &&^&& #@$#@%%& kAR2~thik" | tr 'a-z' 'A-Z'
    # Output:
    # MY NAME IS 123 &&^&& #@0@%%& KAR2~THIK

    将转换后的字符串存储为变量。跟随者为我工作-$SOURCE_NAME$TARGET_NAME

    1
    TARGET_NAME="`echo $SOURCE_NAME | tr '[:upper:]' '[:lower:]'`"


    这是Jaredts486方法的一个更快的变体,它使用本地bash功能(包括bash版本<4.0)来优化他的方法。

    我已经为小字符串(25个字符)和大字符串(445个字符)计时了1000次这种方法的迭代,包括小写和大写转换。由于测试字符串主要是小写的,因此转换为小写通常比转换为大写更快。

    我将我的方法与本页上与bash 3.2兼容的其他几个答案进行了比较。我的方法比这里记录的大多数方法都要有效得多,在某些情况下甚至比tr更快。

    下面是1000次25个字符的迭代的计时结果:

    • 小写字母0.46s;大写字母0.96s
    • 1.16s表示Orwellophile的小写方法;1.59s表示大写
    • 对于tr到小写,3.67s;对于大写,3.81s
    • 11.12s表示GhostDog74的小写方法;31.41s表示大写
    • 26.25s表示Technosaurus的小写字母;26.21s表示大写字母
    • Jaredts486的小写方法为25.06s;大写为27.04s

    1000次445个字符迭代的计时结果(由维特·比纳的诗《罗宾》):

    • 2s表示我的小写;12s表示大写
    • 4s表示从tr到小写;4s表示大写
    • Orwellophile的小写方法为20s;大写为29s
    • GhostDog74的小写方法是75s;大写是669s。有趣的是,注意到一个主要匹配的测试与一个主要未命中的测试之间的性能差异有多大
    • 467s表示Technosaurus的小写字母;449s表示大写字母
    • Jaredts486的小写方法是660s;大写是660s。有趣的是,这种方法在bash中生成连续的页面错误(内存交换)。

    解决方案:

    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
    32
    33
    34
    35
    36
    37
    38
    #!/bin/bash
    set -e
    set -u

    declare LCS="abcdefghijklmnopqrstuvwxyz"
    declare UCS="ABCDEFGHIJKLMNOPQRSTUVWXYZ"

    function lcase()
    {
      local TARGET="${1-}"
      local UCHAR=''
      local UOFFSET=''

      while [["${TARGET}" =~ ([A-Z]) ]]
      do
        UCHAR="${BASH_REMATCH[1]}"
        UOFFSET="${UCS%%${UCHAR}*}"
        TARGET="${TARGET//${UCHAR}/${LCS:${#UOFFSET}:1}}"
      done

      echo -n"${TARGET}"
    }

    function ucase()
    {
      local TARGET="${1-}"
      local LCHAR=''
      local LOFFSET=''

      while [["${TARGET}" =~ ([a-z]) ]]
      do
        LCHAR="${BASH_REMATCH[1]}"
        LOFFSET="${LCS%%${LCHAR}*}"
        TARGET="${TARGET//${LCHAR}/${UCS:${#LOFFSET}:1}}"
      done

      echo -n"${TARGET}"
    }

    方法很简单:当输入字符串中存在任何剩余的大写字母时,找到下一个字母,并用它的小写变体替换该字母的所有实例。重复此操作,直到所有大写字母都被替换。

    我的解决方案的一些性能特征:

  • 只使用shell内置实用程序,这样可以避免在新进程中调用外部二进制实用程序的开销。
  • 避免子shell,这会导致性能惩罚
  • 使用为性能编译和优化的shell机制,例如变量内的全局字符串替换、变量后缀修整以及regex搜索和匹配。这些机制比通过字符串手动迭代快得多。
  • 仅循环要转换的唯一匹配字符计数所需的次数。例如,将具有三个不同大写字符的字符串转换为小写字符只需要3次循环迭代。对于预先配置的ASCII字母表,循环迭代的最大次数为26次
  • UCSLCS可以用附加字符进行扩充。