Come convertire una stringa in minuscolo in Bash?

C’è un modo in bash per convertire una stringa in una stringa in minuscolo?

Ad esempio, se ho:

a="Hi all" 

Voglio convertirlo in:

 "hi all" 

    Sono vari modi:

    TR

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

    AWK

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

    Bash 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 

    Perl

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

    bash

     lc(){ case "$1" in [AZ]) 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 

    In Bash 4:

    In lettere minuscole

     $ 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 

    In maiuscolo

     $ 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 

    Attiva / distriggers (non documentato, ma facoltativamente configurabile in fase di compilazione)

     $ 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 

    Capitalizzare (non documentato, ma facoltativamente configurabile in fase di compilazione)

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

    Titolo:

     $ 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 

    Per distriggersre un attributo declare , usa + . Ad esempio, declare +c string . Ciò influisce sulle assegnazioni successive e non sul valore corrente.

    Le opzioni di declare cambiano l’attributo della variabile, ma non i contenuti. Le riassegnazioni nei miei esempi aggiornano i contenuti per mostrare le modifiche.

    Modificare:

    Aggiunto “triggers / distriggers il primo carattere per parola” ( ${var~} ) come suggerito da ghostdog74 .

    Modifica: corretto comportamento della tilde per abbinare Bash 4.3.

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

    tr :

     a="$(tr [AZ] [az] <<< "$a")" 

    AWK :

     { print tolower($0) } 

    sed :

     y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ 

    So che questo è un post vecchio ma ho fatto questa risposta per un altro sito, quindi ho pensato di postarlo qui:

    ALTO -> inferiore : usa python:

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

    O Ruby:

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

    O Perl (probabilmente il mio preferito):

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

    O PHP:

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

    O Awk:

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

    O Sed:

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

    Oppure Bash 4:

     b=${a,,} 

    O NodeJS se ce l’hai (e sei un po ‘pazzo …):

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

    Puoi anche usare dd (ma non lo farei!):

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

    inferiore -> SUPERIORE :

    usa python:

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

    O Ruby:

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

    O Perl (probabilmente il mio preferito):

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

    O PHP:

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

    O Awk:

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

    O Sed:

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

    Oppure Bash 4:

     b=${a^^} 

    O NodeJS se ce l’hai (e sei un po ‘pazzo …):

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

    Puoi anche usare dd (ma non lo farei!):

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

    Anche quando dici ‘shell’ suppongo tu intenda bash ma se puoi usare zsh è facile come

     b=$a:l 

    per le lettere minuscole e

     b=$a:u 

    per le maiuscole.

    In zsh:

     echo $a:u 

    Devi amare zsh!

    Usando GNU sed :

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

    Esempio:

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

    Per una shell standard (senza bashismi) usando solo 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}" } 

    E per le maiuscole:

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

    Pre Bash 4.0

    Bash Abbassa il caso di una stringa e assegna alla variabile

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

    Espressione regolare

    Mi piacerebbe prendere il merito del comando che desidero condividere, ma la verità è che l’ho ottenuto per mio uso da http://commandlinefu.com . Ha il vantaggio che se si esegue il cd su qualsiasi directory all’interno della propria cartella home, ciò cambierà tutti i file e le cartelle in lettere minuscole in modo ricorsivo, si prega di usare con caucanvas. È una correzione brillante da riga di comando e particolarmente utile per quelle moltitudini di album che hai memorizzato sul tuo disco.

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

    È ansible specificare una directory al posto del punto (.) Dopo il find che indica la directory corrente o il percorso completo.

    Spero che questa soluzione si riveli utile l’unica cosa che questo comando non fa è sostituire gli spazi con caratteri di sottolineatura – oh beh, forse un’altra volta.

    In bash 4 puoi usare typeset

    Esempio:

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

    Puoi provare questo

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

    inserisci la descrizione dell'immagine qui

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

    Se si utilizza la v4, questa viene cotta in forno . In caso contrario, ecco una soluzione semplice e ampiamente applicabile . Altre risposte (e commenti) su questo thread sono state molto utili nella creazione del codice seguente.

     # 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:] )\' } 

    Gli appunti:

    • Doing: a="Hi All" e poi: lcase a farà la stessa cosa di: a=$( echolcase "Hi All" )
    • Nella funzione lcase, l'utilizzo di ${!1//\'/"'\''"} invece di ${!1} consente di funzionare anche quando la stringa ha virgolette.

    Per le versioni di Bash precedenti alla 4.0, questa versione dovrebbe essere più veloce (in quanto non esegue il fork / esegui alcun comando):

     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 [AZ] ) printf -v __decimal '%d' "'$__char" printf -v __octal '%03o' $(( $__decimal ^ 0x20 )) printf -v __char \\$__octal ;; esac __result+="$__char" done REPLY="$__result" } 

    la risposta del tecnosauro aveva anche il potenziale, sebbene funzionasse correttamente per me.

    A dispetto di quanti anni ha questa domanda e simile a questa risposta di technosaurus . Ho avuto difficoltà a trovare una soluzione che fosse portatile su molte piattaforms (That I Use) così come su versioni precedenti di bash. Sono anche stato frustrato con matrici, funzioni e uso di stampe, echi e file temporanei per recuperare variabili banali. Questo funziona molto bene per me finora ho pensato di condividere. I miei principali ambienti di test sono:

    1. GNU bash, versione 4.1.2 (1) -release (x86_64-redhat-linux-gnu)
    2. GNU bash, versione 3.2.57 (1) -release (sparc-sun-solaris2.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 

    Semplice C-style per loop per scorrere le stringhe. Per la riga qui sotto, se non hai visto nulla di simile prima che questo sia dove ho imparato questo . In questo caso la linea controlla se il char $ {input: $ i: 1} (minuscolo) esiste in input e se così lo sostituisce con il dato char $ {ucs: $ j: 1} (maiuscolo) e lo memorizza di nuovo in input.

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

    Molte risposte utilizzano programmi esterni, che in realtà non usano Bash .

    Se sai che Bash4 sarà disponibile, dovresti semplicemente usare la notazione ${VAR,,} (è facile e interessante). Per Bash prima di 4 (My Mac usa ancora Bash 3.2 per esempio). Ho usato la versione corretta della risposta di @ ghostdog74 per creare una versione più portatile.

    Uno puoi chiamare lowercase 'my STRING' e ottenere una versione minuscola. Ho letto commenti sull’impostazione del risultato su var, ma non è molto portabile in Bash , dal momento che non possiamo restituire le stringhe. La stampa è la soluzione migliore. Facile da catturare con qualcosa come var="$(lowercase $str)" .

    Come funziona

    Il modo in cui funziona è ottenere la rappresentazione intera ASCII di ogni carattere con printf e quindi adding 32 se upper-to->lower o subtracting 32 se lower-to->upper . Quindi utilizzare nuovamente printf per convertire il numero in un carattere. Da 'A' -to-> 'a' abbiamo una differenza di 32 caratteri.

    Usando printf per spiegare:

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

    97 - 65 = 32

    E questa è la versione funzionante con esempi.
    Si prega di notare i commenti nel codice, in quanto spiegano un sacco di cose:

     #!/bin/bash # lowerupper.sh # Prints the lowercase version of a char lowercaseChar(){ case "$1" in [AZ]) 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="[email protected]" 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 [az]) 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="[email protected]" 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 "[email protected]" 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 

    E i risultati dopo aver eseguito questo:

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

    Questo dovrebbe funzionare solo per i caratteri ASCII però .

    Per me va bene, dal momento che so che gli passerò solo caratteri ASCII.
    Lo sto usando per alcune opzioni CLI senza distinzione tra maiuscole e minuscole, ad esempio.

    La conversione della custodia viene eseguita solo per gli alfabeti. Quindi, questo dovrebbe funzionare perfettamente.

    Mi sto concentrando sulla conversione di alfabeti tra az da maiuscolo a minuscolo. Qualsiasi altro personaggio dovrebbe essere stampato in stdout così com’è …

    Converte tutto il testo in path / to / file / filename nell’intervallo az in AZ

    Per convertire lettere minuscole in lettere maiuscole

     cat path/to/file/filename | tr 'az' 'AZ' 

    Per la conversione da maiuscolo a minuscolo

     cat path/to/file/filename | tr 'AZ' 'az' 

    Per esempio,

    nome del file:

     my name is xyz 

    viene convertito in:

     MY NAME IS XYZ 

    Esempio 2:

     echo "my name is 123 karthik" | tr 'az' 'AZ' # Output: # MY NAME IS 123 KARTHIK 

    Esempio 3:

     echo "my name is 123 &&^&& #@$#@%%& kAR2~thik" | tr 'az' 'AZ' # Output: # MY NAME IS 123 &&^&& #@[email protected]%%& KAR2~THIK 

    Per memorizzare la stringa trasformata in una variabile. In seguito ha funzionato per me: $SOURCE_NAME su $TARGET_NAME

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

    Questa è una variazione molto più rapida dell’approccio di JaredTS486 che utilizza le funzionalità native di Bash (incluse le versioni di Bash <4.0) per ottimizzare il suo approccio.

    Ho programmato 1.000 iterazioni di questo approccio per una piccola stringa (25 caratteri) e una stringa più grande (445 caratteri), entrambe per le conversioni minuscole e maiuscole. Poiché le stringhe di prova sono prevalentemente in minuscolo, le conversioni in lettere minuscole sono generalmente più veloci che maiuscole.

    Ho confrontato il mio approccio con diverse altre risposte su questa pagina che sono compatibili con Bash 3.2. Il mio approccio è molto più performante della maggior parte degli approcci documentati qui, ed è persino più veloce di tr in diversi casi.

    Ecco i risultati dei tempi per 1.000 iterazioni di 25 caratteri:

    • 0,46 secondi per il mio approccio a lettere minuscole; 0.96s per lettere maiuscole
    • 1,16 per l’approccio di Orwellophile al minuscolo; 1.59 secondi per lettere maiuscole
    • 3.67 s per tr in lettere minuscole; 3.81 s per lettere maiuscole
    • 11.12s per l’approccio di ghostdog74 alle lettere minuscole; 31,41 secondi per lettere maiuscole
    • 26.25 per l’approccio dei technosaurus alle lettere minuscole; 26.21s per lettere maiuscole
    • 25.06s per l’approccio di JaredTS486 a lettere minuscole; 27.04 s per le maiuscole

    Risultati di temporizzazione per 1.000 iterazioni di 445 caratteri (composti dal poema “The Robin” di Witter Bynner):

    • 2s per il mio approccio a lettere minuscole; 12 secondi per lettere maiuscole
    • 4s per tr in minuscolo; 4 secondi per lettere maiuscole
    • Anni ’20 per l’approccio di Orwellophile alla minuscola; 29 per maiuscolo
    • 75s per l’ approccio di ghostdog74 alle lettere minuscole; 669 per maiuscolo. È interessante notare quanto sia drammatica la differenza di prestazioni tra un test con partite predominanti e un test con missioni predominanti
    • 467 per l’approccio dei technosaurus alle lettere minuscole; 449 per maiuscolo
    • 660 per l’approccio di JaredTS486 a lettere minuscole; 660 per maiuscolo. È interessante notare che questo approccio ha generato errori di pagina continui (scambio di memoria) in Bash

    Soluzione:

     #!/bin/bash set -e set -u declare LCS="abcdefghijklmnopqrstuvwxyz" declare UCS="ABCDEFGHIJKLMNOPQRSTUVWXYZ" function lcase() { local TARGET="${1-}" local UCHAR='' local UOFFSET='' while [[ "${TARGET}" =~ ([AZ]) ]] 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}" =~ ([az]) ]] do LCHAR="${BASH_REMATCH[1]}" LOFFSET="${LCS%%${LCHAR}*}" TARGET="${TARGET//${LCHAR}/${UCS:${#LOFFSET}:1}}" done echo -n "${TARGET}" } 

    L’approccio è semplice: mentre la stringa di input presenta le lettere maiuscole rimanenti presenti, trova la successiva e sostituisce tutte le occorrenze di quella lettera con la sua variante in lettere minuscole. Ripeti fino a quando tutte le lettere maiuscole vengono sostituite.

    Alcune caratteristiche di prestazione della mia soluzione:

    1. Utilizza solo le utilità incorporate della shell, che evita il sovraccarico del richiamo di utilità binarie esterne in un nuovo processo
    2. Evita sub-shell, che incorre in penalità prestazionali
    3. Utilizza meccanismi di shell compilati e ottimizzati per le prestazioni, come la sostituzione di stringhe globali all’interno di variabili, il taglio di suffissi variabili e la ricerca e corrispondenza di espressioni regolari. Questi meccanismi sono molto più veloci di iterare manualmente attraverso le stringhe
    4. Ciclo solo per il numero di volte richiesto dal conteggio di caratteri di corrispondenza univoci da convertire. Ad esempio, la conversione di una stringa con tre caratteri maiuscoli diversi in minuscolo richiede solo 3 iterazioni di ciclo. Per l’alfabeto ASCII preconfigurato, il numero massimo di iterazioni del ciclo è 26
    5. UCS e LCS possono essere aumentati con caratteri aggiuntivi