How to convert a string to lower case in Bash?

前端 未结 20 2034
慢半拍i
慢半拍i 2020-11-22 09:40

Is there a way in bash to convert a string into a lower case string?

For example, if I have:

a=\"Hi all\"

I want to convert it to:<

相关标签:
20条回答
  • 2020-11-22 09:53

    You can try this

    s="Hello World!" 
    
    echo $s  # Hello World!
    
    a=${s,,}
    echo $a  # hello world!
    
    b=${s^^}
    echo $b  # HELLO WORLD!
    

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

    0 讨论(0)
  • 2020-11-22 09:53

    If using v4, this is baked-in. If not, here is a simple, widely applicable solution. Other answers (and comments) on this thread were quite helpful in creating the code below.

    # 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//\'/"'\''"} | tr [:upper:] [:lower:] )\'
    }
    

    Notes:

    • Doing: a="Hi All" and then: lcase a will do the same thing as: a=$( echolcase "Hi All" )
    • In the lcase function, using ${!1//\'/"'\''"} instead of ${!1} allows this to work even when the string has quotes.
    0 讨论(0)
  • 2020-11-22 09:54

    Pre Bash 4.0

    Bash Lower the Case of a string and assign to variable

    VARIABLE=$(echo "$VARIABLE" | tr '[:upper:]' '[:lower:]') 
    
    echo "$VARIABLE"
    
    0 讨论(0)
  • 2020-11-22 09:56

    Simple way

    echo "Hi all" | awk '{ print tolower($0); }'
    
    0 讨论(0)
  • 2020-11-22 09:58

    For a standard shell (without bashisms) using only builtins:

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

    And for upper case:

    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}"
    }
    
    0 讨论(0)
  • 2020-11-22 09:58

    This is a far faster variation of JaredTS486's approach that uses native Bash capabilities (including Bash versions <4.0) to optimize his approach.

    I've timed 1,000 iterations of this approach for a small string (25 characters) and a larger string (445 characters), both for lowercase and uppercase conversions. Since the test strings are predominantly lowercase, conversions to lowercase are generally faster than to uppercase.

    I've compared my approach with several other answers on this page that are compatible with Bash 3.2. My approach is far more performant than most approaches documented here, and is even faster than tr in several cases.

    Here are the timing results for 1,000 iterations of 25 characters:

    • 0.46s for my approach to lowercase; 0.96s for uppercase
    • 1.16s for Orwellophile's approach to lowercase; 1.59s for uppercase
    • 3.67s for tr to lowercase; 3.81s for uppercase
    • 11.12s for ghostdog74's approach to lowercase; 31.41s for uppercase
    • 26.25s for technosaurus' approach to lowercase; 26.21s for uppercase
    • 25.06s for JaredTS486's approach to lowercase; 27.04s for uppercase

    Timing results for 1,000 iterations of 445 characters (consisting of the poem "The Robin" by Witter Bynner):

    • 2s for my approach to lowercase; 12s for uppercase
    • 4s for tr to lowercase; 4s for uppercase
    • 20s for Orwellophile's approach to lowercase; 29s for uppercase
    • 75s for ghostdog74's approach to lowercase; 669s for uppercase. It's interesting to note how dramatic the performance difference is between a test with predominant matches vs. a test with predominant misses
    • 467s for technosaurus' approach to lowercase; 449s for uppercase
    • 660s for JaredTS486's approach to lowercase; 660s for uppercase. It's interesting to note that this approach generated continuous page faults (memory swapping) in Bash

    Solution:

    #!/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}"
    }
    

    The approach is simple: while the input string has any remaining uppercase letters present, find the next one, and replace all instances of that letter with its lowercase variant. Repeat until all uppercase letters are replaced.

    Some performance characteristics of my solution:

    1. Uses only shell builtin utilities, which avoids the overhead of invoking external binary utilities in a new process
    2. Avoids sub-shells, which incur performance penalties
    3. Uses shell mechanisms that are compiled and optimized for performance, such as global string replacement within variables, variable suffix trimming, and regex searching and matching. These mechanisms are far faster than iterating manually through strings
    4. Loops only the number of times required by the count of unique matching characters to be converted. For example, converting a string that has three different uppercase characters to lowercase requires only 3 loop iterations. For the preconfigured ASCII alphabet, the maximum number of loop iterations is 26
    5. UCS and LCS can be augmented with additional characters
    0 讨论(0)
提交回复
热议问题