it-swarm.com.de

Wie konvertiert man eine Zeichenfolge in Bash in Kleinbuchstaben?

Gibt es eine Möglichkeit in bash einen String in einen String mit Kleinbuchstaben zu konvertieren?

Zum Beispiel, wenn ich:

a="Hi all"

Ich möchte es konvertieren in:

"hi all"
1008
assassin

Es gibt verschiedene Möglichkeiten:

POSIX-Standard

tr

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

AWK

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

Nicht-POSIX

In den folgenden Beispielen können Probleme mit der Portabilität auftreten:

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
        [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
1779
ghostdog74

In Bash 4:

Kleinschreibung

$ 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

Zu Großbuchstaben

$ 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 (undokumentiert, aber optional zur Kompilierzeit konfigurierbar)

$ 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

Großschreibung (undokumentiert, aber optional zur Kompilierzeit konfigurierbar)

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

Titelfall:

$ 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

Um ein declare-Attribut zu deaktivieren, verwenden Sie +. Zum Beispiel declare +c string. Dies betrifft nachfolgende Zuordnungen und nicht den aktuellen Wert.

Die Optionen declare ändern das Attribut der Variablen, nicht jedoch den Inhalt. Die Neuzuordnungen in meinen Beispielen aktualisieren den Inhalt, um die Änderungen anzuzeigen.

Bearbeiten:

"Erstes Zeichen durch Word umschalten" (${var~}) wie von ghostdog74 vorgeschlagen.

Edit: Das Tilde-Verhalten wurde korrigiert, damit es mit Bash 4.3 übereinstimmt.

383
echo "Hi All" | tr "[:upper:]" "[:lower:]"
116
shuvalov

tr :

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

AWK :

{ print tolower($0) }

sed :

y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/

Ich weiß, dass dies ein alter Beitrag ist, aber ich habe diese Antwort für eine andere Website gemacht, also dachte ich, ich würde ihn hier posten:

UPPER -> lower : Python verwenden:

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

Oder Rubin:

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

Oder Perl (wahrscheinlich mein Favorit):

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

Oder PHP:

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

Oder Awk:

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

Oder Sed:

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

Oder Bash 4:

b=${a,,}

Oder NodeJS, wenn Sie es haben (und ein bisschen verrückt sind ...):

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

Sie könnten auch dd verwenden (würde ich aber nicht!):

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

niedriger -> UPPER :

benutze Python:

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

Oder Rubin:

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

Oder Perl (wahrscheinlich mein Favorit):

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

Oder PHP:

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

Oder Awk:

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

Oder Sed:

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

Oder Bash 4:

b=${a^^}

Oder NodeJS, wenn Sie es haben (und ein bisschen verrückt sind ...):

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

Sie könnten auch dd verwenden (würde ich aber nicht!):

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

Wenn Sie 'Shell' sagen, gehe ich davon aus, dass Sie bash meinen, aber wenn Sie zsh verwenden können, ist das so einfach

b=$a:l

für Kleinbuchstaben und

b=$a:u

für Großbuchstaben.

38
nettux

In zsh:

echo $a:u

Muss zsh lieben!

26
Scott Smedley

Verwendung von GNU sed:

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

Beispiel:

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

Für eine Standard-Shell (ohne Bashismen), die nur Builtins verwendet:

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

Und für Großbuchstaben:

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

Pre Bash 4.0

Bash Senken Sie den Fall einer Zeichenfolge und weisen Sie eine Variable zu

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

echo "$VARIABLE"
10
hawkeye126

In Bash 4 können Sie den Satz verwenden

Beispiel:

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

Regulären Ausdruck

Ich möchte das Kommando, das ich mit Ihnen teilen möchte, würdigen, aber die Wahrheit ist, dass ich es für meinen eigenen Gebrauch von http://commandlinefu.com erhalten habe. Es hat den Vorteil, dass, wenn Sie cd in ein beliebiges Verzeichnis in Ihrem eigenen Home-Ordner wechseln, alle Dateien und Ordner rekursiv in Kleinbuchstaben geändert werden. Es ist eine brillante Befehlszeilen-Korrektur und besonders nützlich für die Vielzahl von Alben, die Sie auf Ihrem Laufwerk gespeichert haben.

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

Sie können anstelle des Punktes (.) Ein Verzeichnis angeben, das das aktuelle Verzeichnis oder den vollständigen Pfad angibt.

Ich hoffe, dass diese Lösung sich als nützlich erweist. Dieses Kommando tut nichts, indem Leerzeichen durch Unterstriche ersetzt werden - ein anderes Mal vielleicht.

7
Derek Shaw

Sie können es versuchen

s="Hello World!" 

echo $s  # Hello World!

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

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

 enter image description here

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

6
Bikesh M Annur

Trotz wie alt ist diese Frage und diese Antwort von Technosaurus . Es fiel mir schwer, eine Lösung zu finden, die auf den meisten Plattformen (That I Use) sowie älteren Versionen von Bash portierbar war. Ich war auch frustriert mit Arrays, Funktionen und der Verwendung von Drucken, Echos und temporären Dateien, um triviale Variablen abzurufen. Das funktioniert sehr gut für mich, bis ich dachte, ich würde es teilen ... Meine Haupttestumgebungen sind: 

  1. GNU bash, Version 4.1.2 (1) -release (x86_64-redhat-linux-gnu) 
  2. GNU bash, Version 3.2.57 (1) -freigabe (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

Einfacher C-Stil für Schleife zum Durchlaufen der Strings . Für die folgende Zeile, falls Sie zuvor noch nie etwas davon gesehen haben hier habe ich das gelernt . In diesem Fall prüft die Zeile, ob das Zeichen $ {input: $ i: 1} (Kleinbuchstaben) in der Eingabe vorhanden ist, und ersetzt dies durch das angegebene Zeichen $ {ucs: $ j: 1} (Großbuchstaben) und speichert es zurück in die Eingabe.

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

Bei früheren Bash-Versionen als 4.0 sollte diese Version am schnellsten sein (da fork/exec keine Befehle enthält):

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's answer hatte auch Potenzial, obwohl es für mich richtig lief.

3
Orwellophile

Bei Verwendung von v4 ist dies eingebacken . Wenn nicht, ist hier eine einfache, weithin anwendbare Lösung. Andere Antworten (und Kommentare) zu diesem Thread waren beim Erstellen des folgenden Codes sehr hilfreich.

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

Anmerkungen:

  • Tun: a="Hi All" und dann: lcase a wird dasselbe tun wie: a=$( echolcase "Hi All" )
  • Wenn Sie in der lcase-Funktion ${!1//\'/"'\''"} anstelle von ${!1} verwenden, funktioniert dies auch, wenn der String Anführungszeichen enthält.
3

Viele Antworten mit externen Programmen, die Bash nicht wirklich verwenden.

Wenn Sie wissen, dass Sie Bash4 zur Verfügung haben, sollten Sie einfach die ${VAR,,}-Schreibweise verwenden (es ist einfach und cool). Für Bash vor 4 (Mein Mac verwendet beispielsweise noch Bash 3.2). Ich habe die korrigierte Version von @ ghostdog74 verwendet, um eine portable Version zu erstellen.

Sie können lowercase 'my STRING' aufrufen und eine Kleinbuchstabenversion erhalten. Ich lese Kommentare zum Festlegen des Ergebnisses auf eine Variable, aber das ist in Bash nicht wirklich portabel, da wir keine Zeichenfolgen zurückgeben können. Drucken ist die beste Lösung. Mit etwas wie var="$(lowercase $str)" einfach zu erfassen. 

Wie das funktioniert

Die Funktionsweise besteht darin, die Ganzzahldarstellung ASCII jedes Zeichens mit printf und dann adding 32 wenn upper-to->lower oder subtracting 32 wenn lower-to->upper abzurufen. Verwenden Sie dann erneut printf, um die Zahl wieder in ein Zeichen umzuwandeln. Bei 'A' -to-> 'a' unterscheiden wir 32 Zeichen.

Verwendung von printf zur Erklärung:

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

97 - 65 = 32

Und das ist die Arbeitsversion mit Beispielen.
Bitte beachten Sie die Kommentare im Code, da sie eine Menge Dinge erklären:

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

Und die Ergebnisse nach dem Ausführen:

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

Dies sollte nur für ASCII -Zeichen funktionieren, obwohl

Für mich ist es in Ordnung, da ich weiß, dass ich nur ASCII Zeichen an ihn übergeben werde.
Ich verwende dies beispielsweise für einige CLI-Optionen ohne Berücksichtigung der Groß- und Kleinschreibung.

3
Gus Neves

Wenn Sie Python mögen und die Möglichkeit haben, ein neues Python-Paket zu installieren, können Sie dieses Python-Dienstprogramm ausprobieren.

# install pythonp
$ pip install pythonp

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

Der Fall wird nur für Alphabete konvertiert. Das sollte also ordentlich funktionieren.

Ich konzentriere mich auf die Umwandlung von Alphabeten zwischen a-z von Großbuchstaben zu Kleinbuchstaben. Alle anderen Zeichen sollten einfach in stdout gedruckt werden.

Konvertiert den gesamten Text in Pfad/in/Datei/Dateiname im A-Z-Bereich in A-Z

Zur Umwandlung von Kleinbuchstaben in Großbuchstaben

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

Zum Umrüsten von Groß- zu Kleinschreibung

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

Zum Beispiel,

dateiname:

my name is xyz

wird umgewandelt in:

MY NAME IS XYZ

Beispiel 2

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

Beispiel 3:

echo "my name is 123 &&^&& #@$#@%%& kAR2~thik" | tr 'a-z' 'A-Z'
# Output:
# MY NAME IS 123 &&^&& #@[email protected]%%& KAR2~THIK
1
theBuzzyCoder

Um den transformierten String in eine Variable zu speichern. Folgendes arbeitete für mich -$SOURCE_NAME bis $TARGET_NAME 

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

Dies ist eine viel schnellere Variante des Ansatzes von JaredTS486 , der native Bash-Funktionen (einschließlich Bash-Versionen <4.0) zur Optimierung seines Ansatzes verwendet.

Ich habe 1.000 Iterationen dieses Ansatzes für eine kleine Zeichenfolge (25 Zeichen) und eine größere Zeichenfolge (445 Zeichen) festgelegt, sowohl für die Konvertierung in Kleinbuchstaben als auch in Großbuchstaben. Da die Testzeichenfolgen überwiegend aus Kleinbuchstaben bestehen, sind Konvertierungen in Kleinbuchstaben im Allgemeinen schneller als in Großbuchstaben.

Ich habe meinen Ansatz mit mehreren anderen Antworten auf dieser Seite verglichen, die mit Bash 3.2 kompatibel sind. Mein Ansatz ist weitaus performanter als die meisten hier dokumentierten Ansätze und in einigen Fällen sogar schneller als tr.

Hier sind die Timing-Ergebnisse für 1.000 Iterationen von 25 Zeichen:

Timing-Ergebnisse für 1.000 Iterationen mit 445 Zeichen (bestehend aus dem Gedicht "The Robin" von Witter Bynner):

  • 2s für meine Herangehensweise an Kleinbuchstaben; 12s für Großbuchstaben
  • 4s für tr in Kleinbuchstaben; 4s für Großbuchstaben
  • 20s für Orwellophiles Herangehensweise an Kleinbuchstaben; 29s für Großbuchstaben
  • 75s für ghostdog74s Annäherung an Kleinbuchstaben; 669s für Großbuchstaben. Es ist interessant festzustellen, wie dramatisch der Leistungsunterschied zwischen einem Test mit vorherrschenden Spielen und einem Test mit vorherrschenden Fehlern ist
  • 467s für technosaurus 'Ansatz in Kleinbuchstaben; 449s für Großbuchstaben
  • 660s für JaredTS486s Herangehensweise an Kleinbuchstaben; 660s für Großbuchstaben. Es ist interessant festzustellen, dass dieser Ansatz in Bash zu fortlaufenden Seitenfehlern (Memory Swapping) führte

Lösung:

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

Der Ansatz ist einfach: Während die Eingabezeichenfolge noch aus Großbuchstaben besteht, suchen Sie den nächsten und ersetzen Sie alle Instanzen dieses Buchstabens durch seine Kleinbuchstabenvariante. Wiederholen Sie diesen Vorgang, bis alle Großbuchstaben ersetzt sind.

Einige Leistungsmerkmale meiner Lösung:

  1. Verwendet nur von Shell integrierte Dienstprogramme, wodurch der Aufwand für das Aufrufen externer binärer Dienstprogramme in einem neuen Prozess vermieden wird
  2. Vermeidet Sub-Shells, die zu Leistungseinbußen führen
  3. Verwendet Shell-Mechanismen, die für die Leistung kompiliert und optimiert wurden, z. B. das Ersetzen von globalen Zeichenfolgen in Variablen, das Trimmen von Variablensuffixen sowie das Suchen und Vergleichen von regulären Ausdrücken. Diese Mechanismen sind viel schneller als das manuelle Durchlaufen von Strings
  4. Schleifen nur, wie oft die Anzahl der übereinstimmenden Zeichen für die Konvertierung erforderlich ist. Wenn Sie beispielsweise eine Zeichenfolge mit drei verschiedenen Großbuchstaben in Kleinbuchstaben konvertieren, sind nur drei Durchläufe erforderlich. Für das vorkonfigurierte Alphabet ASCII beträgt die maximale Anzahl von Schleifeniterationen 26
  5. UCS und LCS können mit zusätzlichen Zeichen erweitert werden
0
Dejay Clayton