Konvertieren Sie den gesamten Text von Groß- in Kleinbuchstaben und umgekehrt?

17

Meine Frage ist, wie ich den gesamten Text von Groß- in Kleinbuchstaben und umgekehrt konvertieren kann. Das heißt, die Groß- und Kleinschreibung aller Buchstaben zu ändern. Es muss sedirgendwie mit einem Ersatz getan werden .

MEZesUBI
quelle
4
trwäre besser geeignet als sed.
Choroba

Antworten:

20

Hier ist ein gerader Weg in sed:

$ echo qWeRtY | sed -e 'y/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/'
QwErTy

oder ein kürzerer Weg mit GNU sed, mit jedem Zeichen zu arbeiten, für das in Ihrem Gebietsschema eine Konvertierung in Kleinbuchstaben <-> in Großbuchstaben existiert:

$ echo qWeRtY | sed -E 's/([[:lower:]])|([[:upper:]])/\U\1\L\2/g'
QwErTy

wenn Sie andere Tools verwenden können, wie:

perl (beschränkt auf ASCII-Buchstaben):

$ echo qWeRtY | perl -pe 'y/[a-z][A-Z]/[A-Z][a-z]/'
QwErTy

perl (allgemeiner):

$ echo 'αΒγ' | perl -Mopen=locale -pe 's/(\p{Ll})|(\p{Lu})/uc($1).lc($2)/ge'
ΑβΓ
cuonglm
quelle
3
Ihre zweite geht von einer GNU sedund einer alternativen Schreibweise in der Eingabe aus. Verwenden Sie sed -re 's/([[:lower:]]?)([[:upper:]]?)/\U\1\L\2/g'stattdessen (immer noch GNU-spezifisch). Der erste konvertiert nur die 26 lateinischen ASCII-Buchstaben, während der zweite alle Buchstaben konvertiert, die von Ihrem Gebietsschema als solche erkannt wurden. Das trmacht nur in ASCII-Sprachumgebungen Sinn. Der perleine funktioniert nur für lateinische ASCII-Buchstaben.
Stéphane Chazelas
16

POSIXly, das ist nur möglich, sedwenn Sie den vollständigen Satz von Buchstaben bereitstellen, die Sie transliterieren möchten, wie @cuonglm gezeigt hat .

Es könnte aber gemacht werden tr, und das ist, wofür tr(transliterate):

tr '[:lower:][:upper:]' '[:upper:][:lower:]'

Unter Linux gibt es jedoch Einschränkungen. Von den drei trImplementierungen, die häufig auf Linux-basierten Systemen zu finden sind:

  • Mit GNU trfunktioniert das nur für Einzelbyte-Zeichensätze. Zum Beispiel auf Stéphane Chazelasin UTF-8-Gebietsschemas, die sTéPHANE cHAZELASanstelle von gibt sTÉPHANE cHAZELAS. Das ist eine bekannte Einschränkung von GNU tr.
  • Mit trdem Erbstück-Werkzeugkasten funktioniert das nicht stéphane chazelas.
  • So etwas macht busybox trnicht.

Unter FreeBSD funktioniert das jedoch einwandfrei. Sie würden erwarten, dass es auch in zertifizierten Unix-Systemen einwandfrei funktioniert.


Die bashShell hat dafür einen eigenen Operator:

in=AbCdE
out=${in~~}

Mit zsh -o extendedglob:

out=${in//(#b)(([[:lower:]])|([[:upper:]]))/${(U)match[2]}${(L)match[3]}}
Stéphane Chazelas
quelle
Also in der Desktop-Welt macht es nur OSX? Warum kann es nicht funktionieren? Handelt es sich nur um die verschiedenen Implementierungen, da der Hexadezimalwert einen konstanten Versatz zwischen der Kleinbuchstabenversion des akzentuierten Zeichens und seinem Gegenstück in Großbuchstaben aufweist?
1
@ illuminÉ, nicht sicher, was du mit Desktop-Welt meinst . AFAICS, das Problem ist mit GNU, die meisten Unices haben "Desktops". Abgesehen von ASCII und einigen iso8859-Zeichensätzen bin ich mir nicht bewusst, dass Sie das Hex-Offset-Ding verallgemeinern können, und das würde mit Codierungen wie UTF-8 keinen Sinn ergeben. Zum Beispiel in UTF-8 ist Großbuchstabe (e2 b4 a0) (e1 83 80); Sowohl i(69) als auch ı(c4 b1) haben I(49) als Großbuchstaben (außer in türkischen Gebietsschemata, wo iwird İ). Der Grund, warum es mit GNU nicht funktioniert, trist, dass GNU trmit Bytes und nicht mit Zeichen arbeitet.
Stéphane Chazelas
Ich meinte irgendwie Mainstream, aber es macht keinen Sinn, also danke für das Heads-up. Ich habe mir nur die Zeichen mit französischem Akzent (und wirklich nur "é") angesehen und sehr vereinfachende Annahmen getroffen, wobei ich wieder vergessen habe, dass es sich um Bytes handelt. Aber das Erbstück? Ich werde diese Antwort noch einmal lesen!
1
@ illuminÉ, für Erbstücke ist es ein anderes Problem, es scheint nur ein Vorkommen von [:lower:]oder zu unterstützen [:upper:](das erste wird ignoriert). Auch in Französisch œ -> Œist c5 93 -> c5 92in UTF-8 und bd -> bcin ISO8859-15.
Stéphane Chazelas
2

Dies hat zwar dieselben Einschränkungen wie die trvon Stéphane Chazelas angebotene Lösung, ist jedoch eine andere Möglichkeit:

{   echo QWERTYqwerty | dd conv=lcase
    echo QWERTYqwerty | dd conv=ucase 
} 2>/dev/null

AUSGABE

qwertyqwerty
QWERTYQWERTY

Ich Dump stderrin /dev/nulldort , weil ddauch Statistiken aller seiner Operationen auf dem bietet 2Dateideskriptor. Dies kann nützlich sein, je nachdem, was Sie tun, war aber nicht für diese Demonstration. Alle anderen Dinge, die Sie damit machen können, gelten ddweiterhin, zum Beispiel:

echo QWERTYqwerty | dd bs=1 cbs=6 conv=unblock,ucase 2>/dev/null

AUSGABE:

QWERTY
QWERTY
mikeserv
quelle
Der Fall wird jedoch nicht vertauscht (da in aBcnicht konvertiert wird AbC).
Stéphane Chazelas
1
@ StéphaneChazelas - stimmt, aber wenn ich nicht falsch verstanden habe, war das nicht die Frage, oder?
mikeserv
2

Wenn Ihr Hauptziel darin besteht, eine Datei von Unterklasse zu Oberklasse zu konvertieren , warum verwenden Sie diese nicht trund STDOUTkonvertieren Ihre Datei:

$cat FILENAME | tr a-z A-Z > FILENAME2

Wo FILENAMEist deine Originaldatei? Wo FILENAME2ist Ihre konvertierte Ausgabedatei?

Rick
quelle
Es hat nicht funktioniert mit Zeichen mit Akzent, wie ézum Beispiel (zumindest in meiner Datei).
Sigur
1

mit awk:

awk '{print tolower($0)}' file.txt | tee file.txt
Hackaholic
quelle
Bist du sicher, dass das funktionieren wird? >file.txtwürde mit dem Abschneiden der Datei beginnen
iruvar
2
Dann hast du es offensichtlich nicht ausprobiert.
Stéphane Chazelas
0

ruby hat eine String-Methode dafür, ähnlich wie bei der Kommandozeile perl

$ echo 'qWeRtY' | ruby -pe '$_.swapcase!'
QwErTy

Siehe auch ruby-doc-Kodierung

$ ruby -e 'puts Encoding.default_external'
UTF-8
$ echo 'αΒγ'  | ruby -pe '$_.swapcase!'
ΑβΓ
Sundeep
quelle
-1

Halte die einfache Sache einfach. Der Filter für die Übersetzung von Zeichen lautet tr.

echo 1ude1UDE | tr [:upper:][:lower:] [:lower:][:upper:]
Rogelio
quelle
1
Das ist eine kaputte (wegen der fehlenden Anführungszeichen um die Globbing-Operatoren) Version einer Antwort, die bereits 2 Jahre zuvor gegeben wurde
Stéphane Chazelas