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"
Es gibt verschiedene Möglichkeiten:
$ echo "$a" | tr '[:upper:]' '[:lower:]'
hi all
$ echo "$a" | awk '{print tolower($0)}'
hi all
In den folgenden Beispielen können Probleme mit der Portabilität auftreten:
$ echo "${a,,}"
hi all
$ echo "$a" | sed -e 's/\(.*\)/\L\1/'
hi all
# this also works:
$ sed -e 's/\(.*\)/\L\1/' <<< "$a"
hi all
$ echo "$a" | Perl -ne 'print lc'
hi all
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
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.
echo "Hi All" | tr "[:upper:]" "[:lower:]"
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.
In zsh:
echo $a:u
Muss zsh lieben!
Verwendung von GNU sed
:
sed 's/.*/\L&/'
Beispiel:
$ foo="Some STRIng";
$ foo=$(echo "$foo" | sed 's/.*/\L&/')
$ echo "$foo"
some string
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}"
}
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"
In Bash 4 können Sie den Satz verwenden
Beispiel:
A="HELLO WORLD"
typeset -l A=$A
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.
Sie können es versuchen
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/
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:
- GNU bash, Version 4.1.2 (1) -release (x86_64-redhat-linux-gnu)
- 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}}"
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.
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:
a="Hi All"
und dann: lcase a
wird dasselbe tun wie: a=$( echolcase "Hi All" )
${!1//\'/"'\''"}
anstelle von ${!1}
verwenden, funktioniert dies auch, wenn der String Anführungszeichen enthält.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.
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()"
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
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:]'`"
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:
tr
in Kleinbuchstaben; 3,81s für GroßbuchstabenTiming-Ergebnisse für 1.000 Iterationen mit 445 Zeichen (bestehend aus dem Gedicht "The Robin" von Witter Bynner):
tr
in Kleinbuchstaben; 4s für GroßbuchstabenLö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:
UCS
und LCS
können mit zusätzlichen Zeichen erweitert werden