Ich habe eine temp
-Datei mit einigen Klein- und Großbuchstaben.
Eingabe
Inhalt meiner temp
-Datei:
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 eine falsche Ausgabe erhalten.
Ausgabe
Ich möchte es als:
hi jigar gandhi jiga
Was muss im Ersatzteil sein? des Arguments für sed
?
Kommentare
Antwort
Wenn Ihre Eingabe nur ASCII-Zeichen enthält, können Sie tr
wie folgt verwenden:
oder (weniger leicht zu merken und IMO einzugeben; aber nicht beschränkt auf lateinische ASCII-Buchstaben, obwohl in einigen Implementierungen, einschließlich GNU tr
, immer noch auf Einzelbyte-Zeichen beschränkt ist, also in UTF-8-Gebietsschemas immer noch auf ASCII-Buchstaben beschränkt):
tr "[:upper:]" "[:lower:]" < input
, wenn Sie sed
verwenden müssen:
sed "s/.*/\L&/g" < input
(hier unter der Annahme der GNU-Implementierung).
Mit POSIX sed
müssen Sie alle Transliterationen angeben und können dann auswählen, welche Buchstaben, die Sie konvertieren möchten:
sed "y/AǼBCΓDEFGH.../aǽbcγdefgh.../" < input
Mit awk
:
awk "{print tolower($0)}" < input
Kommentare
- Bitte beachten Sie, dass
\L
eine GNU-Erweiterung ist. -
\L
funktioniert bisher gut für mich. Beleuchten Sie den Punkt, an dem Sie versuchen, eine GNU-Erweiterung - @JigarGandhi vorzunehmen.
sed
ist ein Unix-Befehl. Unterschiedliche Systeme haben unterschiedliche Varianten mit unterschiedlichem Verhalten d 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.\L
gehört nicht dazu und wurde von GNUsed
eingeführt (entspricht demselben Operator im Standardex
/vi
) und ist in anderen Implementierungen im Allgemeinen nicht verfügbar. - Beachten Sie, dass einige
tr
-Implementierungen wie GNUtr
‚ funktioniert in Multi-Byte-Gebietsschemas nicht ordnungsgemäß (die meisten von ihnen versuchen heutzutageecho STÉPHANE | tr '[:upper:]' '[:lower:]'
zum Beispiel). Auf GNU-Systemen bevorzugen Sie möglicherweise die Variantesed
oderawk
‚ stolower()
. - Leichte Korrektur:
sed 's/.*/\L&/g' < input
. Der Verweis\1
auf die übereinstimmende Teilzeichenfolge ‚ funktioniert nur, wenn Sie die Teilzeichenfolge in Klammern angeben, wie dies bei wurtle der Fall ist. ‚ ist jedoch etwas sauberer, wenn Sie&
verwenden, um die gesamte Übereinstimmung darzustellen, wie gezeigt
Antwort
Mit vim ist das ganz einfach:
$ vim filename gg0guGZZ
Wird geöffnet Die Datei gg
geht in die erste Zeile, 0
, erste Spalte. Mit guG
, senkt die Groß- und Kleinschreibung aller Zeichen bis zum Ende der Datei. ZZ
speichert und beendet.
Es sollte fast alles verarbeiten, was Sie darauf werfen „Zahlen ignorieren, es wird nicht ASCII verarbeiten.
Wenn Sie das Gegenteil tun möchten, wandeln Sie die Kleinbuchstaben in Großbuchstaben um und tauschen Sie die u
aus out für ein U
: gg0gUGZZ
und Sie sind eingestellt.
Kommentare
- Lol “ super einfach “
- dies ist offensichtlich nicht ‚ Für viele Dateien nicht gut skalierbar
- @CoreyGoldberg
vim file1 file2 fileetc
und dann würde so etwas wie:bufdo gg0guG:w<CR>
wahrscheinlich arbeite für eine beliebige Anzahl von Dateien. Habe das aber nicht getestet! - @TankorSmash, das ‚ immer noch nicht auf eine große Anzahl von Dateien
Antwort
Ich mag dd
dafür selbst.
<<\IN LC_ALL=C 2<>/dev/null \ dd conv=lcase hi Jigar GANDHI jiga IN
… erhält …
hi jigar ghandi jiga
Die LC_ALL=C
dient zum Schutz von Multibytes in der Eingabe – obwohl Multibyte-Großbuchstaben nicht konvertiert werden. Gleiches gilt für (GNU) tr
– beide Apps neigen dazu, in einem Nicht-C-Gebietsschema Mangeln einzugeben. iconv
kann für eine umfassende Lösung mit beiden kombiniert werden.
Die Umleitung 2>/dev/null
verwirft den Standardstatusbericht von dd
– und dessen stderr. Ohne ihn dd
würde nach Abschluss eines Auftrags wie dem oben genannten mit Druckinformationen wie der Anzahl der verarbeiteten Bytes usw. folgen.
Kommentare
- Diese Lösung ist viel schneller als
tr
beim Umgang mit großen Dateien, danke!
Antwort
Sie können auch Perl 5 verwenden:
perl -pe "$_=lc" temp
Die Option -p
sagt perl, um den angegebenen Ausdruck einmal für jede Eingabezeile auszuführen und das Ergebnis zu drucken, dh den Endwert von $_
. -e
gibt an, dass die Das Programm ist das nächste Argument im Gegensatz zu einer Datei, die das Skript enthält. lc
wird in Kleinbuchstaben konvertiert. Ohne Argument wird $_
. Und $_=
speichert das erneut, damit es gedruckt wird.
Eine Variation davon wäre
perl -ne "print lc" temp
Verwenden von -n
ist wie -p
, außer dass $_
am Ende nicht gedruckt wird. Anstatt in dieser Variablen zu speichern, füge ich eine explizite Druckanweisung 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 eine Perl-Abhängigkeit haben. Im Vergleich zu tr
kann es sein, dass Perl lc
leichter auf das Gebietsschema aufmerksam gemacht werden kann. Weitere Informationen finden Sie in der Manpage perllocale
.
Antwort
Sie müssen erfassen das übereinstimmende Muster und verwenden Sie es dann beim Ersetzen durch einen Modifikator:
sed "s/\([A-Z]\)/\L\1/g" temp
Die \(...\)
„erfasst“ die Bei übereinstimmendem Text geht die erste Erfassung an \1
, die nächste an \2
usw. Die Nummerierung richtet sich nach den öffnenden Klammern bei verschachtelte Erfassungen.
Die \L
konvertiert das erfasste Muster in Kleinbuchstaben. Es gibt auch \U
für Großbuchstaben
Kommentare
- Sie müssen dies nicht tun – das gesamte Muster wird immer in
&
abgefangen - Stimmt, aber dann hätte ich die Gelegenheit verpasst, das Erfassen von Übereinstimmungen zu erklären 🙂
Antwort
Neben der Antwort von MvG können Sie auch Perl 6 verwenden:
perl6 -pe .=lc temp
Hier ist $ _ implizit, und Sie benötigen keine einfachen Anführungszeichen, um es vor der Erweiterung durch die Shell zu schützen ($ _ ist ein spezieller Bash-Parameter; Siehe: https://www.gnu.org/software/bash/manual/html_node/Special-Parameters.html )