How to convert a string to lower case in Bash?

前端 未结 20 2392
慢半拍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条回答
  •  猫巷女王i
    2020-11-22 10:07

    Many answers using external programs, which is not really using Bash.

    If you know you will have Bash4 available you should really just use the ${VAR,,} notation (it is easy and cool). For Bash before 4 (My Mac still uses Bash 3.2 for example). I used the corrected version of @ghostdog74 's answer to create a more portable version.

    One you can call lowercase 'my STRING' and get a lowercase version. I read comments about setting the result to a var, but that is not really portable in Bash, since we can't return strings. Printing it is the best solution. Easy to capture with something like var="$(lowercase $str)".

    How this works

    The way this works is by getting the ASCII integer representation of each char with printf and then adding 32 if upper-to->lower, or subtracting 32 if lower-to->upper. Then use printf again to convert the number back to a char. From 'A' -to-> 'a' we have a difference of 32 chars.

    Using printf to explain:

    $ printf "%d\n" "'a"
    97
    $ printf "%d\n" "'A"
    65
    

    97 - 65 = 32

    And this is the working version with examples.
    Please note the comments in the code, as they explain a lot of stuff:

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

    And the results after running this:

    $ ./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!
    

    This should only work for ASCII characters though.

    For me it is fine, since I know I will only pass ASCII chars to it.
    I am using this for some case-insensitive CLI options, for example.

提交回复
热议问题