Konvertieren Sie Dateiinhalte in Kleinbuchstaben

85

Ich habe eine tempDatei mit Klein- und Großbuchstaben.

Eingang

Inhalt meiner tempDatei:

hi
Jigar
GANDHI
jiga

Ich möchte alle oberen in untere konvertieren .

Befehl

Ich habe den folgenden Befehl ausprobiert:

sed -e "s/[A-Z]/[a-z]/g" temp

habe aber falsche ausgabe bekommen.

Ausgabe

Ich möchte es als:

hi
jigar
gandhi
jiga

Wofür muss der Ersatzteil des Arguments stehen sed?

JigarGandhi
quelle

Antworten:

122

Wenn Ihre Eingabe nur ASCII-Zeichen enthält, können Sie Folgendes verwenden tr:

tr A-Z a-z < input 

oder (weniger leicht zu merken und IMO einzugeben; jedoch nicht beschränkt auf lateinische ASCII-Buchstaben, obwohl in einigen Implementierungen, einschließlich GNU tr, weiterhin beschränkt auf Einzelbyte-Zeichen, also in UTF-8-Gebietsschemata, weiterhin beschränkt auf ASCII-Buchstaben):

tr '[:upper:]' '[:lower:]' < input

wenn du verwenden musst sed:

sed 's/.*/\L&/g' < input

(hier unter der Annahme der GNU-Implementierung).

Bei POSIX sedmüssen Sie alle Transliterationen angeben und dann können Sie auswählen, welche Buchstaben Sie konvertieren möchten:

sed 'y/AǼBCΓDEFGH.../aǽbcγdefgh.../' < input

Mit awk:

awk '{print tolower($0)}' < input
Anthon
quelle
3
Bitte beachten Sie, dass dies \Leine GNU-Erweiterung ist.
Anthon
\Lfunktioniert soweit gut bei mir En beleuchten Sie den Punkt, dass Sie versuchen, GNU-Erweiterung
JigarGandhi
2
@JigarGandhi. sedist ein Unix-Befehl. Unterschiedliche Systeme haben unterschiedliche Varianten mit unterschiedlichem Verhalten und unterschiedlicher Funktionalität. Zum Glück gibt es heutzutage einen Standard, der den meisten Anforderungen entspricht, sodass Sie sich auf ein Minimum an Funktionen verlassen können, die allen gemeinsam sind. \List nicht unter ihnen und wurde von GNU eingeführt sed(entspricht dem gleichen Operator in standard ex/ vi) und ist in der Regel in anderen Implementierungen nicht verfügbar.
Stéphane Chazelas
9
Beachten Sie, dass einige trImplementierungen wie GNU trin Mehrbyte-Gebietsschemas nicht richtig funktionieren (die meisten von ihnen sind heutzutage, versuchen Sie es echo STÉPHANE | tr '[:upper:]' '[:lower:]'zum Beispiel). Auf GNU - Systemen können Sie die bevorzugen sedVariante oder awk‚s tolower().
Stéphane Chazelas
5
Leichte Korrektur: sed 's/.*/\L&/g' < input. Der \1Verweis auf die übereinstimmende Teilzeichenfolge funktioniert nur, wenn Sie die Teilzeichenfolge in Klammern angeben, wie dies bei wurtle der Fall ist. Es ist jedoch etwas sauberer, um &das gesamte Spiel darzustellen, wie gezeigt
Edward Brown
30

Mit vim ist es ganz einfach:

$ vim filename
gg0guGZZ

Öffnet die Datei, gggeht in die erste Zeile 0, erste Spalte. Mit guGwird die Groß- / Kleinschreibung aller Zeichen bis zum Ende der Datei verringert. ZZspeichert und beendet.

Es sollte fast alles verarbeiten, was Sie darauf werfen. Zahlen werden ignoriert, Nicht-ASCII-Zeichen werden verarbeitet.

Wenn Sie das Gegenteil tun möchten, wandeln Sie die Buchstaben in Großbuchstaben um, tauschen Sie die Buchstaben ugegen a U: aus, gg0gUGZZund fertig.

TankorSmash
quelle
14
Lol "super einfach"
blambert
Dies ist offensichtlich für viele Dateien nicht gut skalierbar
Corey Goldberg
meine bisher beliebteste Antwort !!!!
Mona Jalal
1
@Coreygoldberg vim file1 file2 fileetcund dann sowas :bufdo gg0guG:w<CR>würde wohl für beliebig viele dateien funktionieren. Habe das allerdings nicht getestet!
TankorSmash
@ TankorSmash, die immer noch nicht auf eine große Anzahl von Dateien skaliert
Corey Goldberg
17

Ich mag dddas selbst.

<<\IN LC_ALL=C 2<>/dev/null \
dd conv=lcase
hi
Jigar 
GANDHI
jiga
IN

... bekommt ...

hi
jigar
ghandi
jiga

Das LC_ALL=Cist kein multibytes in Eingang zu schützen - auch wenn alle multibyte Kapitelle werden nicht konvertiert. Das Gleiche gilt für (GNU) tr - beide Apps neigen dazu, in einem Nicht-C-Gebietsschema Unregelmäßigkeiten einzugeben. iconvkann für eine umfassende Lösung mit beiden kombiniert werden.

Der Standardstatusbericht der 2>/dev/nullUmleitung wird verworfen dd- und der dazugehörige Stderr. Andernfalls ddwürde die Fertigstellung eines Auftrags wie oben beschrieben mit Druckinformationen wie der Anzahl der verarbeiteten Bytes usw. erfolgen.

mikeserv
quelle
Diese Lösung ist viel schneller als trbeim Umgang mit großen Dateien, danke!
WhiteWinterWolf
13

Sie können auch Perl 5 verwenden:

perl -pe '$_=lc' temp

Die Option -pweist Perl an, den angegebenen Ausdruck einmal für jede Eingabezeile auszuführen und das Ergebnis, dh den Endwert von, zu drucken $_. -eGibt an, dass das Programm das nächste Argument ist, im Gegensatz zu einer Datei, die das Skript enthält. lckonvertiert in Kleinbuchstaben. Ohne ein Argument wird es weiterarbeiten $_. Und $_=speichert es erneut, damit es gedruckt wird.

Eine Variation davon wäre

perl -ne 'print lc' temp

Verwenden -nist wie -pnur, dass $_es am Ende nicht gedruckt wird. Anstatt diese Variable zu speichern, füge ich eine explizite print-Anweisung hinzu.

Ein Vorteil von Perl im Gegensatz zu sed ist, dass Sie keine GNU-Erweiterungen benötigen. Es gibt Projekte, die mit Nicht-GNU-Umgebungen kompatibel sein müssen, aber auch bereits Perl als Abhängigkeit haben. Im Vergleich trdazu könnte es sein, dass Perl lcleichter für das Gebietsschema sensibilisiert werden kann. perllocaleEinzelheiten finden Sie auf der Manpage.

MvG
quelle
9

Sie müssen das übereinstimmende Muster erfassen und dann in der Ersetzung durch einen Modifikator verwenden:

sed 's/\([A-Z]\)/\L\1/g' temp

Das \(...\)"erfasst" den einschließenden passenden Text, das erste Capture geht an \1, das nächste an \2usw. Die Nummerierung richtet sich nach den öffnenden Klammern bei verschachtelten Captures.

Das \Lkonvertiert das erfasste Muster in Kleinbuchstaben, es gibt auch \UGroßbuchstaben.

wurtel
quelle
3
Sie brauchen das nicht zu tun - das ganze Muster ist immer in&
mikeserv
Stimmt, aber dann hätte ich die Gelegenheit verpasst, das Erfassen von Übereinstimmungen zu erklären :-)
Wurtel