Hinweis: YMMV in diesem Fall. Funktioniert bei mir nicht (GNU Bash Version 4.2.46 und 4.0.33 (und gleiches Verhalten 2.05b.0, aber Nocasematch ist nicht implementiert)), selbst bei Verwendung shopt -u nocasematch;. Das Deaktivieren dieser Nichtübereinstimmung führt dazu, dass [["fooBaR" == "FOObar"]] mit OK übereinstimmt, ABER im Fall, dass [bz] seltsamerweise mit [AZ] falsch übereinstimmt. Bash wird durch das Doppel-Negativ verwirrt ("Nocasematch nicht setzen")! :-)
Vermisse ich etwas oder macht Ihr letztes Beispiel (in Bash) tatsächlich etwas völlig anderes? Es funktioniert für "ABX", aber wenn Sie stattdessen word="Hi All"wie die anderen Beispiele machen, wird es hanicht zurückgegeben hi all. Es funktioniert nur für Großbuchstaben und überspringt die bereits in Kleinbuchstaben geschriebenen Buchstaben.
Jangosteve
26
Beachten Sie, dass im POSIX-Standard nur die Beispiele trund awkangegeben sind.
Richard Hansen
178
tr '[:upper:]' '[:lower:]'verwendet das aktuelle Gebietsschema, um Groß- / Kleinbuchstaben zu ermitteln, sodass es mit Gebietsschemas funktioniert, die Buchstaben mit diakritischen Zeichen verwenden.
Richard Hansen
10
Wie bekommt man die Ausgabe in eine neue Variable? Das heißt, ich möchte die Zeichenfolge in Kleinbuchstaben in eine neue Variable umwandeln?
Adam Parkin
60
@ Adam:b="$(echo $a | tr '[A-Z]' '[a-z]')"
Tino
435
In Bash 4:
In Kleinbuchstaben
$ string="A FEW WORDS"
$ echo "${string,}"
a FEW WORDS
$ echo "${string,,}"
a few words
$ echo "${string,,[AEIUO]}"
a FeWWoRDS
$ string="A Few Words"
$ declare -l string
$ string=$string; echo "$string"
a few words
In 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
Umschalten (undokumentiert, aber zur Kompilierungszeit optional 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 zur Kompilierungszeit optional 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 FewWords
$ declare -c string
$ string=(a few words)
$ echo "${string[@]}"
A FewWords
$ string="a FeW WOrdS"
$ string=${string,,}
$ string=${string~}
$ echo "$string"
A few words
declareVerwenden Sie zum Deaktivieren eines Attributs +. Zum Beispiel declare +c string. Dies wirkt sich auf nachfolgende Zuordnungen und nicht auf den aktuellen Wert aus.
Die declareOptionen ändern das Attribut der Variablen, nicht jedoch den Inhalt. Die Neuzuweisungen in meinen Beispielen aktualisieren den Inhalt, um die Änderungen anzuzeigen.
Bearbeiten:
Es wurde "erstes Zeichen nach Wort umschalten " ( ${var~}) hinzugefügt, wie von ghostdog74 vorgeschlagen .
Bearbeiten: Das Tilde-Verhalten wurde korrigiert, um mit Bash 4.3 übereinzustimmen.
Ziemlich bizzare, "^^" - und ",," -Operatoren funktionieren nicht mit Nicht-ASCII-Zeichen, aber "~~" funktioniert ... string="łódź"; echo ${string~~}Gibt also "ŁÓDŹ" zurück, gibt aber echo ${string^^}"łóDź" zurück. Auch in LC_ALL=pl_PL.utf-8. Das ist Bash 4.2.24.
Hubert Kario
2
@ HubertKario: Das ist komisch. Es ist dasselbe für mich in Bash 4.0.33 mit der gleichen Zeichenfolge in en_US.UTF-8. Es ist ein Fehler und ich habe ihn gemeldet.
Bis auf weiteres angehalten.
1
@ HubertKario: Versuchen Sie es echo "$string" | tr '[:lower:]' '[:upper:]'. Es wird wahrscheinlich den gleichen Fehler aufweisen. Das Problem ist also zumindest teilweise nicht das von Bash.
Bis auf weiteres angehalten.
1
@ TennisWilliamson: Ja, das habe ich auch bemerkt (siehe Kommentar zur Antwort von Shuvalov). Ich würde nur sagen, "dieses Zeug ist nur für ASCII", aber dann funktioniert der Operator "~~", also ist es nicht so, dass der Code und die Übersetzungstabellen nicht bereits vorhanden sind ...
Hubert Kario
4
@HubertKario: Die Bash Maintainer hat bestätigt den Fehler und erklärte , dass es in der nächsten Version behoben werden.
@ RichardHansen: trfunktioniert bei mir nicht für Nicht-ACII-Zeichen. Ich habe korrekte Gebietsschemasätze und Gebietsschemadateien generiert. Haben Sie eine Idee, was ich falsch machen könnte?
Hubert Kario
Zu Ihrer Information: Dies funktionierte unter Windows / Msys. Einige der anderen Vorschläge haben dies nicht getan.
+1 a="$(tr [A-Z] [a-z] <<< "$a")"sieht für mich am einfachsten aus. Ich bin noch ein Anfänger ...
Sandeepan Nath
2
Ich empfehle die sedLösung nachdrücklich . Ich habe in einer Umgebung gearbeitet, die es aus irgendeinem Grund nicht gibt, traber ich habe noch kein System ohne gefunden sed. Außerdem habe ich die meiste Zeit, in der ich dies tun möchte, sedsowieso etwas anderes getan, damit ich es verketten kann die Befehle zusammen zu einer einzigen (langen) Anweisung.
Haravikk
2
Die Klammerausdrücke sollten in Anführungszeichen gesetzt werden. In tr [A-Z] [a-z] Akann die Shell eine Dateinamenerweiterung durchführen, wenn Dateinamen aus einem einzelnen Buchstaben bestehen oder ein Nullgob festgelegt ist. tr "[A-Z]" "[a-z]" Awird sich richtig verhalten.
Dennis
2
@CamiloMartin Es ist ein BusyBox-System, bei dem ich dieses Problem habe, insbesondere bei Synology NASes, aber ich habe es auch auf einigen anderen Systemen festgestellt. Ich habe in letzter Zeit viel plattformübergreifendes Shell-Scripting durchgeführt, und mit der Anforderung, dass nichts extra installiert werden muss, macht es die Dinge sehr schwierig! Allerdings habe ich noch kein System ohnesed
Haravikk
2
Beachten Sie, dass dies tr [A-Z] [a-z]in fast allen Ländereinstellungen falsch ist. Im en-USGebietsschema A-Zist beispielsweise das Intervall angegeben AaBbCcDdEeFfGgHh...XxYyZ.
Fuz
44
Ich weiß, dass dies ein alter Beitrag ist, aber ich habe diese Antwort für eine andere Website gegeben, also dachte ich, ich würde sie hier veröffentlichen:
UPPER -> lower : Verwenden Sie Python:
b=`echo "print '$a'.lower()" | python`
Oder Ruby:
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 ...):
@JESii beide arbeiten für mich oben -> unten und unten-> oben. Ich verwende sed 4.2.2 und Bash 4.3.42 (1) auf 64-Bit-Debian-Stretch.
Nettux
1
Hallo, @ nettux443 ... Ich habe gerade die Bash-Operation erneut versucht und sie schlägt für mich immer noch mit der Fehlermeldung "Bad Substitution" fehl. Ich bin unter OSX mit Homebrews Bash: GNU Bash, Version 4.3.42 (1) -Veröffentlichung (x86_64-apple-darwin14.5.0)
JESii
5
Verwende nicht! Alle Beispiele, die ein Skript generieren, sind extrem spröde. Wenn der Wert von aein einfaches Anführungszeichen enthält, haben Sie nicht nur ein fehlerhaftes Verhalten, sondern auch ein ernstes Sicherheitsproblem.
Tripleee
Ich mag die sed-Lösung am meisten, da sed immer allgegenwärtig ist.
Dudi Boy
Ich bevorzuge die Verwendung der dd-Lösung. Bitte beachten Sie, dass Sie root sein müssen, damit es funktioniert
Ich frage mich, ob Sie in diesem Skript keinen Bashismus zugelassen haben, da es auf FreeBSD nicht portierbar ist. Sh: $ {1: $ ...}: Schlechte Substitution
Dereckson
2
Tatsächlich; Teilzeichenfolgen mit ${var:1:1}sind ein Baschismus.
Tripleee
Dieser Ansatz weist ziemlich schlechte Leistungsmetriken auf. Siehe meine Antwort für Metriken.
Ich möchte den Befehl, den ich teilen möchte, gutschreiben, aber die Wahrheit ist, dass ich ihn für meinen eigenen Gebrauch von http://commandlinefu.com erhalten habe . Es hat den Vorteil, dass wenn Sie cdin ein Verzeichnis in Ihrem eigenen Home-Ordner wechseln, alle Dateien und Ordner rekursiv in Kleinbuchstaben geändert werden, verwenden Sie diese bitte mit Vorsicht. Es ist eine brillante Befehlszeilenkorrektur und besonders nützlich für die Vielzahl von Alben, die Sie auf Ihrem Laufwerk gespeichert haben.
Sie können anstelle des Punkts (.) Nach der Suche ein Verzeichnis angeben, das das aktuelle Verzeichnis oder den vollständigen Pfad angibt.
Ich hoffe, diese Lösung erweist sich als nützlich. Das einzige, was dieser Befehl nicht tut, ist, Leerzeichen durch Unterstriche zu ersetzen - na ja, vielleicht ein anderes Mal.
Das hat bei mir aus irgendeinem Grund nicht funktioniert, obwohl es gut aussieht. Ich habe dies jedoch als Alternative zum Laufen gebracht: Finden. -exec / bin / bash -c 'mv {} `tr [AZ] [az] <<< {}`' \;
John Rix
Dies muss prenamevon perl: dpkg -S "$(readlink -e /usr/bin/rename)"gibtperl: /usr/bin/prename
Tino
4
Viele Antworten mit externen Programmen, die nicht wirklich verwendet werden Bash.
Wenn Sie wissen, dass Sie Bash4 zur Verfügung haben, sollten Sie wirklich nur die ${VAR,,}Notation verwenden (es ist einfach und cool). Für Bash vor 4 (Mein Mac verwendet zum Beispiel immer noch Bash 3.2). Ich habe die korrigierte Version der Antwort von @ ghostdog74 verwendet, um eine portablere Version zu erstellen.
Eine, die Sie anrufen lowercase 'my STRING'und eine Kleinbuchstabenversion erhalten können. Ich habe Kommentare zum Setzen des Ergebnisses auf eine Variable gelesen, aber das ist nicht wirklich portabel Bash, da wir keine Zeichenfolgen zurückgeben können. Drucken ist die beste Lösung. Einfach mit so etwas zu erfassen var="$(lowercase $str)".
Wie das funktioniert
Dies funktioniert, indem die ASCII-Ganzzahldarstellung jedes Zeichens mit printfund dann adding 32if upper-to->loweroder subtracting 32if abgerufen wird lower-to->upper. Verwenden Sie dann printferneut, um die Zahl wieder in ein Zeichen umzuwandeln. Von haben 'A' -to-> 'a'wir einen Unterschied von 32 Zeichen.
Verwenden printf, um zu erklären:
$ printf "%d\n""'a"97
$ printf "%d\n""'A"65
97 - 65 = 32
Und dies ist die Arbeitsversion mit Beispielen.
Bitte beachten Sie die Kommentare im Code, da sie viele 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="$@"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 likeif[['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 jedoch nur für ASCII-Zeichen funktionieren .
Für mich ist es in Ordnung, da ich weiß, dass ich nur ASCII-Zeichen weitergeben werde.
Ich verwende dies zum Beispiel für einige CLI-Optionen, bei denen die Groß- und Kleinschreibung nicht berücksichtigt wird.
Das Konvertieren von Groß- und Kleinschreibung erfolgt nur für Alphabete. Das sollte also ordentlich funktionieren.
Ich konzentriere mich auf die Konvertierung von Alphabeten zwischen az von Groß- in Kleinbuchstaben. Alle anderen Zeichen sollten so wie sie sind in stdout gedruckt werden ...
Konvertiert den gesamten Text im Pfad / in / Datei / Dateiname im Az-Bereich in AZ
Zum Konvertieren von Kleinbuchstaben in Großbuchstaben
cat path/to/file/filename | tr 'a-z''A-Z'
Zum Konvertieren von Groß- in Kleinbuchstaben
cat path/to/file/filename | tr 'A-Z''a-z'
Zum Beispiel,
Dateiname:
my name is xyz
wird konvertiert zu:
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 &&^&& #@0@%%& KAR2~THIK
Wenn Sie v4 verwenden, ist dies eingebrannt . Wenn nicht, finden Sie hier eine einfache, allgemein 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 awird das Gleiche tun wie:a=$( echolcase "Hi All" )
In der Funktion lcase ermöglicht die Verwendung von ${!1//\'/"'\''"}anstelle von, ${!1}dass dies auch dann funktioniert, wenn die Zeichenfolge Anführungszeichen enthält.
Nicht schlecht! Eine Analyse der Leistung dieses Ansatzes finden Sie in meiner Antwort für Metriken.
Dejay Clayton
3
Trotz des Alters dieser Frage und ähnlich dieser Antwort von Technosaurus . Es fiel mir schwer, eine Lösung zu finden, die auf den meisten Plattformen (die ich verwende) sowie auf älteren Versionen von Bash portabel war. Ich war auch frustriert über Arrays, Funktionen und die Verwendung von Ausdrucken, Echos und temporären Dateien zum Abrufen trivialer Variablen. Das funktioniert sehr gut für mich, bis jetzt dachte ich, ich würde teilen. Meine Haupttestumgebungen sind:
GNU Bash, Version 4.1.2 (1) -Veröffentlichung (x86_64-redhat-linux-gnu)
GNU Bash, Version 3.2.57 (1) -Veröffentlichung (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}}"fidonedone
Einfache C-artige for-Schleife zum Durchlaufen der Zeichenfolgen. Für die folgende Zeile, wenn Sie so etwas noch nicht gesehen haben, habe
ich dies hier gelernt . In diesem Fall prüft die Zeile, ob das Zeichen $ {input: $ i: 1} (Kleinbuchstaben) in der Eingabe vorhanden ist, und ersetzt es in diesem Fall durch das angegebene Zeichen $ {ucs: $ j: 1} (Großbuchstaben) und speichert es zurück in die Eingabe.
Dies ist äußerst ineffizient, da in Ihrem obigen Beispiel eine 650-fache Schleife durchgeführt wird und 35 Sekunden benötigt werden, um 1000 Aufrufe auf meinem Computer auszuführen. Eine Alternative, die nur elf Mal wiederholt wird und weniger als 5 Sekunden benötigt, um 1000 Aufrufe auszuführen, finden Sie in meiner alternativen Antwort.
Dejay Clayton
1
Danke, obwohl das schon beim Betrachten offensichtlich sein sollte. Möglicherweise sind die Seitenfehler auf die Eingabegröße und die Anzahl der von Ihnen ausgeführten Iterationen zurückzuführen. Trotzdem gefällt mir deine Lösung.
JaredTS486
3
Dies ist eine weitaus schnellere Variante des Ansatzes von JaredTS486 , bei dem native Bash-Funktionen (einschließlich Bash-Versionen <4.0) verwendet werden, um seinen Ansatz zu optimieren.
Ich habe 1.000 Iterationen dieses Ansatzes für eine kleine Zeichenfolge (25 Zeichen) und eine größere Zeichenfolge (445 Zeichen) zeitlich festgelegt, sowohl für Konvertierungen in Klein- als auch in Großbuchstaben. Da die Testzeichenfolgen überwiegend in Kleinbuchstaben geschrieben sind, 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 leistungsfähiger als die meisten hier dokumentierten Ansätze und sogar schneller als trin einigen Fällen.
Hier sind die Timing-Ergebnisse für 1.000 Iterationen mit 25 Zeichen:
0,46 s für meine Herangehensweise an Kleinbuchstaben; 0,96s für Großbuchstaben
75s für Ghostdog74s Herangehensweise an Kleinbuchstaben; 669s für Großbuchstaben. Es ist interessant festzustellen, wie dramatisch der Leistungsunterschied zwischen einem Test mit vorherrschenden Übereinstimmungen und einem Test mit vorherrschenden Fehlern ist
660er Jahre für JaredTS486s Herangehensweise an Kleinbuchstaben; 660er für Großbuchstaben. Es ist interessant festzustellen, dass dieser Ansatz in Bash zu kontinuierlichen Seitenfehlern (Speicheraustausch) führte
Der Ansatz ist einfach: Während in der Eingabezeichenfolge noch Großbuchstaben vorhanden sind, suchen Sie den nächsten und ersetzen Sie alle Instanzen dieses Buchstabens durch seine Kleinbuchstabenvariante. Wiederholen, bis alle Großbuchstaben ersetzt sind.
Einige Leistungsmerkmale meiner Lösung:
Verwendet nur integrierte Shell-Dienstprogramme, wodurch der Aufwand für das Aufrufen externer Binärdienstprogramme in einem neuen Prozess vermieden wird
Vermeidet Unterschalen, die Leistungseinbußen verursachen
Verwendet Shell-Mechanismen, die kompiliert und für die Leistung optimiert sind, z. B. das Ersetzen globaler Zeichenfolgen innerhalb von Variablen, das Trimmen von Variablensuffixen sowie das Suchen und Abgleichen von Regex. Diese Mechanismen sind weitaus schneller als das manuelle Durchlaufen von Zeichenfolgen
Schleift nur die Häufigkeit, die für die Anzahl der zu konvertierenden eindeutigen übereinstimmenden Zeichen erforderlich ist. Zum Konvertieren einer Zeichenfolge mit drei verschiedenen Großbuchstaben in Kleinbuchstaben sind beispielsweise nur drei Schleifeniterationen erforderlich. Für das vorkonfigurierte ASCII-Alphabet beträgt die maximale Anzahl von Schleifeniterationen 26
UCSund LCSkann mit zusätzlichen Zeichen erweitert werden
Antworten:
Es gibt verschiedene Möglichkeiten:
POSIX-Standard
tr
AWK
Nicht-POSIX
Bei den folgenden Beispielen können Portabilitätsprobleme auftreten:
Bash 4.0
sed
Perl
Bash
Hinweis: YMMV in diesem Fall. Funktioniert bei mir nicht (GNU Bash Version 4.2.46 und 4.0.33 (und gleiches Verhalten 2.05b.0, aber Nocasematch ist nicht implementiert)), selbst bei Verwendung
shopt -u nocasematch;
. Das Deaktivieren dieser Nichtübereinstimmung führt dazu, dass [["fooBaR" == "FOObar"]] mit OK übereinstimmt, ABER im Fall, dass [bz] seltsamerweise mit [AZ] falsch übereinstimmt. Bash wird durch das Doppel-Negativ verwirrt ("Nocasematch nicht setzen")! :-)quelle
word="Hi All"
wie die anderen Beispiele machen, wird esha
nicht zurückgegebenhi all
. Es funktioniert nur für Großbuchstaben und überspringt die bereits in Kleinbuchstaben geschriebenen Buchstaben.tr
undawk
angegeben sind.tr '[:upper:]' '[:lower:]'
verwendet das aktuelle Gebietsschema, um Groß- / Kleinbuchstaben zu ermitteln, sodass es mit Gebietsschemas funktioniert, die Buchstaben mit diakritischen Zeichen verwenden.b="$(echo $a | tr '[A-Z]' '[a-z]')"
In Bash 4:
In Kleinbuchstaben
In Großbuchstaben
Umschalten (undokumentiert, aber zur Kompilierungszeit optional konfigurierbar)
Großschreibung (undokumentiert, aber zur Kompilierungszeit optional konfigurierbar)
Titelfall:
declare
Verwenden Sie zum Deaktivieren eines Attributs+
. Zum Beispieldeclare +c string
. Dies wirkt sich auf nachfolgende Zuordnungen und nicht auf den aktuellen Wert aus.Die
declare
Optionen ändern das Attribut der Variablen, nicht jedoch den Inhalt. Die Neuzuweisungen in meinen Beispielen aktualisieren den Inhalt, um die Änderungen anzuzeigen.Bearbeiten:
Es wurde "erstes Zeichen nach Wort umschalten " (
${var~}
) hinzugefügt, wie von ghostdog74 vorgeschlagen .Bearbeiten: Das Tilde-Verhalten wurde korrigiert, um mit Bash 4.3 übereinzustimmen.
quelle
string="łódź"; echo ${string~~}
Gibt also "ŁÓDŹ" zurück, gibt aberecho ${string^^}
"łóDź" zurück. Auch inLC_ALL=pl_PL.utf-8
. Das ist Bash 4.2.24.en_US.UTF-8
. Es ist ein Fehler und ich habe ihn gemeldet.echo "$string" | tr '[:lower:]' '[:upper:]'
. Es wird wahrscheinlich den gleichen Fehler aufweisen. Das Problem ist also zumindest teilweise nicht das von Bash.quelle
tr
funktioniert bei mir nicht für Nicht-ACII-Zeichen. Ich habe korrekte Gebietsschemasätze und Gebietsschemadateien generiert. Haben Sie eine Idee, was ich falsch machen könnte?[:upper:]
benötigt?tr :
AWK :
sed :
quelle
a="$(tr [A-Z] [a-z] <<< "$a")"
sieht für mich am einfachsten aus. Ich bin noch ein Anfänger ...sed
Lösung nachdrücklich . Ich habe in einer Umgebung gearbeitet, die es aus irgendeinem Grund nicht gibt,tr
aber ich habe noch kein System ohne gefundensed
. Außerdem habe ich die meiste Zeit, in der ich dies tun möchte,sed
sowieso etwas anderes getan, damit ich es verketten kann die Befehle zusammen zu einer einzigen (langen) Anweisung.tr [A-Z] [a-z] A
kann die Shell eine Dateinamenerweiterung durchführen, wenn Dateinamen aus einem einzelnen Buchstaben bestehen oder ein Nullgob festgelegt ist.tr "[A-Z]" "[a-z]" A
wird sich richtig verhalten.sed
tr [A-Z] [a-z]
in fast allen Ländereinstellungen falsch ist. Imen-US
GebietsschemaA-Z
ist beispielsweise das Intervall angegebenAaBbCcDdEeFfGgHh...XxYyZ
.Ich weiß, dass dies ein alter Beitrag ist, aber ich habe diese Antwort für eine andere Website gegeben, also dachte ich, ich würde sie hier veröffentlichen:
UPPER -> lower : Verwenden Sie Python:
Oder Ruby:
Oder Perl (wahrscheinlich mein Favorit):
Oder PHP:
Oder Awk:
Oder Sed:
Oder Bash 4:
Oder NodeJS, wenn Sie es haben (und ein bisschen verrückt sind ...):
Sie könnten auch verwenden
dd
(aber ich würde nicht!):niedriger -> OBER :
Verwenden Sie Python:
Oder Ruby:
Oder Perl (wahrscheinlich mein Favorit):
Oder PHP:
Oder Awk:
Oder Sed:
Oder Bash 4:
Oder NodeJS, wenn Sie es haben (und ein bisschen verrückt sind ...):
Sie könnten auch verwenden
dd
(aber ich würde nicht!):Auch wenn Sie "Shell" sagen, nehme ich an, Sie meinen,
bash
aber wenn Sie es verwenden können, istzsh
es so einfach wiefür Kleinbuchstaben und
für Großbuchstaben.
quelle
a
ein einfaches Anführungszeichen enthält, haben Sie nicht nur ein fehlerhaftes Verhalten, sondern auch ein ernstes Sicherheitsproblem.In zsh:
Muss ich lieben zsh!
quelle
echo ${(C)a} #Upcase the first char only
Verwenden von GNU
sed
:Beispiel:
quelle
Pre Bash 4.0
Bash Senken Sie die Groß- / Kleinschreibung einer Zeichenfolge und weisen Sie sie einer Variablen zu
quelle
echo
und Rohre: Verwendung$(tr '[:upper:]' '[:lower:]' <<<"$VARIABLE")
Für eine Standard-Shell (ohne Bashismen), die nur eingebaute verwendet:
Und für Großbuchstaben:
quelle
${var:1:1}
sind ein Baschismus.In Bash 4 können Sie den Satz verwenden
Beispiel:
quelle
Sie können dies versuchen
Ref: http://wiki.workassis.com/shell-script-convert-text-to-lowercase-and-uppercase/
quelle
Regulären Ausdruck
Ich möchte den Befehl, den ich teilen möchte, gutschreiben, aber die Wahrheit ist, dass ich ihn für meinen eigenen Gebrauch von http://commandlinefu.com erhalten habe . Es hat den Vorteil, dass wenn Sie
cd
in ein Verzeichnis in Ihrem eigenen Home-Ordner wechseln, alle Dateien und Ordner rekursiv in Kleinbuchstaben geändert werden, verwenden Sie diese bitte mit Vorsicht. Es ist eine brillante Befehlszeilenkorrektur und besonders nützlich für die Vielzahl von Alben, die Sie auf Ihrem Laufwerk gespeichert haben.Sie können anstelle des Punkts (.) Nach der Suche ein Verzeichnis angeben, das das aktuelle Verzeichnis oder den vollständigen Pfad angibt.
Ich hoffe, diese Lösung erweist sich als nützlich. Das einzige, was dieser Befehl nicht tut, ist, Leerzeichen durch Unterstriche zu ersetzen - na ja, vielleicht ein anderes Mal.
quelle
prename
vonperl
:dpkg -S "$(readlink -e /usr/bin/rename)"
gibtperl: /usr/bin/prename
Viele Antworten mit externen Programmen, die nicht wirklich verwendet werden
Bash
.Wenn Sie wissen, dass Sie Bash4 zur Verfügung haben, sollten Sie wirklich nur die
${VAR,,}
Notation verwenden (es ist einfach und cool). Für Bash vor 4 (Mein Mac verwendet zum Beispiel immer noch Bash 3.2). Ich habe die korrigierte Version der Antwort von @ ghostdog74 verwendet, um eine portablere Version zu erstellen.Eine, die Sie anrufen
lowercase 'my STRING'
und eine Kleinbuchstabenversion erhalten können. Ich habe Kommentare zum Setzen des Ergebnisses auf eine Variable gelesen, aber das ist nicht wirklich portabelBash
, da wir keine Zeichenfolgen zurückgeben können. Drucken ist die beste Lösung. Einfach mit so etwas zu erfassenvar="$(lowercase $str)"
.Wie das funktioniert
Dies funktioniert, indem die ASCII-Ganzzahldarstellung jedes Zeichens mit
printf
und dannadding 32
ifupper-to->lower
odersubtracting 32
if abgerufen wirdlower-to->upper
. Verwenden Sie dannprintf
erneut, um die Zahl wieder in ein Zeichen umzuwandeln. Von haben'A' -to-> 'a'
wir einen Unterschied von 32 Zeichen.Verwenden
printf
, um zu erklären:97 - 65 = 32
Und dies ist die Arbeitsversion mit Beispielen.
Bitte beachten Sie die Kommentare im Code, da sie viele Dinge erklären:
Und die Ergebnisse nach dem Ausführen:
Dies sollte jedoch nur für ASCII-Zeichen funktionieren .
Für mich ist es in Ordnung, da ich weiß, dass ich nur ASCII-Zeichen weitergeben werde.
Ich verwende dies zum Beispiel für einige CLI-Optionen, bei denen die Groß- und Kleinschreibung nicht berücksichtigt wird.
quelle
Das Konvertieren von Groß- und Kleinschreibung erfolgt nur für Alphabete. Das sollte also ordentlich funktionieren.
Ich konzentriere mich auf die Konvertierung von Alphabeten zwischen az von Groß- in Kleinbuchstaben. Alle anderen Zeichen sollten so wie sie sind in stdout gedruckt werden ...
Konvertiert den gesamten Text im Pfad / in / Datei / Dateiname im Az-Bereich in AZ
Zum Konvertieren von Kleinbuchstaben in Großbuchstaben
Zum Konvertieren von Groß- in Kleinbuchstaben
Zum Beispiel,
Dateiname:
wird konvertiert zu:
Beispiel 2:
Beispiel 3:
quelle
Wenn Sie v4 verwenden, ist dies eingebrannt . Wenn nicht, finden Sie hier eine einfache, allgemein anwendbare Lösung. Andere Antworten (und Kommentare) zu diesem Thread waren beim Erstellen des folgenden Codes sehr hilfreich.
Anmerkungen:
a="Hi All"
und dann:lcase a
wird das Gleiche tun wie:a=$( echolcase "Hi All" )
${!1//\'/"'\''"}
anstelle von,${!1}
dass dies auch dann funktioniert, wenn die Zeichenfolge Anführungszeichen enthält.quelle
Für Bash-Versionen vor 4.0 sollte diese Version am schnellsten sein (da keine Befehle gegabelt / ausgeführt werden):
Die Antwort von technosaurus hatte auch Potenzial, obwohl sie für mich richtig lief.
quelle
Trotz des Alters dieser Frage und ähnlich dieser Antwort von Technosaurus . Es fiel mir schwer, eine Lösung zu finden, die auf den meisten Plattformen (die ich verwende) sowie auf älteren Versionen von Bash portabel war. Ich war auch frustriert über Arrays, Funktionen und die Verwendung von Ausdrucken, Echos und temporären Dateien zum Abrufen trivialer Variablen. Das funktioniert sehr gut für mich, bis jetzt dachte ich, ich würde teilen. Meine Haupttestumgebungen sind:
Einfache C-artige for-Schleife zum Durchlaufen der Zeichenfolgen. Für die folgende Zeile, wenn Sie so etwas noch nicht gesehen haben, habe ich dies hier gelernt . In diesem Fall prüft die Zeile, ob das Zeichen $ {input: $ i: 1} (Kleinbuchstaben) in der Eingabe vorhanden ist, und ersetzt es in diesem Fall durch das angegebene Zeichen $ {ucs: $ j: 1} (Großbuchstaben) und speichert es zurück in die Eingabe.
quelle
Dies ist eine weitaus schnellere Variante des Ansatzes von JaredTS486 , bei dem native Bash-Funktionen (einschließlich Bash-Versionen <4.0) verwendet werden, um seinen Ansatz zu optimieren.
Ich habe 1.000 Iterationen dieses Ansatzes für eine kleine Zeichenfolge (25 Zeichen) und eine größere Zeichenfolge (445 Zeichen) zeitlich festgelegt, sowohl für Konvertierungen in Klein- als auch in Großbuchstaben. Da die Testzeichenfolgen überwiegend in Kleinbuchstaben geschrieben sind, 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 leistungsfähiger als die meisten hier dokumentierten Ansätze und sogar schneller als
tr
in einigen Fällen.Hier sind die Timing-Ergebnisse für 1.000 Iterationen mit 25 Zeichen:
tr
Kleinbuchstaben; 3,81s für GroßbuchstabenTiming-Ergebnisse für 1.000 Iterationen von 445 Zeichen (bestehend aus dem Gedicht "The Robin" von Witter Bynner):
tr
Kleinbuchstaben; 4s für GroßbuchstabenLösung:
Der Ansatz ist einfach: Während in der Eingabezeichenfolge noch Großbuchstaben vorhanden sind, suchen Sie den nächsten und ersetzen Sie alle Instanzen dieses Buchstabens durch seine Kleinbuchstabenvariante. Wiederholen, bis alle Großbuchstaben ersetzt sind.
Einige Leistungsmerkmale meiner Lösung:
UCS
undLCS
kann mit zusätzlichen Zeichen erweitert werdenquelle
Speichern der transformierten Zeichenfolge in einer Variablen. Das Folgende hat bei mir funktioniert -
$SOURCE_NAME
zu$TARGET_NAME
quelle
Einfacher Weg
quelle