Ich habe eine Textdatei, deren Inhalt ist:
i k k
Wenn ich wc -m
zum Zählen von Zeichennummern in dieser Datei verwende, ist das Ergebnis 7 .
Frage 1: Aber warum habe ich 7 bekommen, sollte ich nicht " 6 " bekommen, vorausgesetzt, es zählt das " Zeilenende " -Zeichen?
Frage 2: Wie genau funktioniert das wc -m
?
Frage 3: Wenn ich wc -c
(zum Zählen von Byte-Nummern) verwende, erhalte ich dasselbe Ergebnis wie wc -m
. Worum geht es also, wenn ich zwei verschiedene Optionen habe ? Sie machen genau den gleichen Job, nicht wahr? Wenn nicht, was ist der Unterschied und wie wc -c
funktioniert es?
command-line
wc
SWIIWII
quelle
quelle
Antworten:
Sie sollten dort in der Tat nur 6 Zeichen haben. Versuche zu rennen
Anzeigen der nicht druckbaren Zeichen Ihrer Datei. Sie müssen etwas extra haben. Wenn ich eine Datei wie Ihre erstelle, verstehe ich
Hast du ein Leerzeichen gesetzt? Das würde 7 ergeben:
i k k $
oder vielleicht hat es eine neue Zeile:das ist auch 7
Wie du sagst
zählt Zeichen und
zählt Bytes. Wenn alle Ihre Zeichen Teil des ASCII-Zeichensatzes sind, gibt es nur 1 Byte pro Zeichen, sodass Sie von beiden Befehlen die gleiche Anzahl erhalten.
Probieren Sie eine Datei mit Nicht-ASCII-Zeichen aus:
Aha! Jetzt mehr Bytes als Zeichen.
quelle
cat -A
würde das auch zeigen. Ich fügte meiner Antwort hinzu, danke :)`likethis`
, damit er lesbar ist, nicht fettIn meiner aktuellen Umgebung ist der Zeichensatz UTF-8, dh Zeichen werden mit 1 bis 4 Bytes pro Zeichen codiert (obwohl die ursprüngliche Definition von UTF-8 zulässigen Zeichencodepunkten bis 0x7fffffff die meisten Tools UTF- 8-Byte-Sequenzen von bis zu 6 Byte).
In diesem Zeichensatz stehen alle Zeichen aus Unicode zur Verfügung, a
a
ist beispielsweise als Bytewert 65, a乕
als 3-é
Byte-Sequenz 228 185 149 und als Zwei-Byte-Sequenz 195 169 codiert .Jetzt:
Ich habe meine Umgebung geändert, in der der Zeichensatz jetzt ISO-8859-15 ist (andere Dinge wie Sprache, Währungssymbol, Datumsformat wurden ebenfalls geändert, die Sammlung dieser regionalen Einstellungen wird als Gebietsschema bezeichnet ). In dieser Umgebung muss ein neuer Terminal-Emulator gestartet werden, damit die Zeichenwiedergabe an das neue Gebietsschema angepasst werden kann.
ISO-8859-15 ist ein Einzelbyte-Zeichensatz, der nur 256 Zeichen enthält (tatsächlich werden sogar weniger als die tatsächlich abgedeckten Zeichen verwendet). Dieser spezielle Zeichensatz wird für westeuropäische Sprachen verwendet, da er die meisten seiner Sprachen (und das Euro-Symbol) abdeckt.
Es hat das
a
Zeichen mit dem Bytewert 65 wie in UTF-8 oder ASCII, es hat auch dasé
Zeichen (wie es beispielsweise in Französisch oder Spanisch gebräuchlich ist), aber mit dem Bytewert 233 hat es nicht das Zeichen 乕.In dieser Umgebung
wc -c
undwc -m
wird immer das gleiche Ergebnis geben.In Ubuntu wie auf den meisten modernen Unix-ähnlichen Systemen ist die Standardeinstellung normalerweise UTF-8, da dies der einzige unterstützte Zeichensatz (und die einzige Codierung) ist, die den gesamten Unicode-Bereich abdeckt.
Es gibt andere Mehrbyte-Zeichenkodierungen, aber sie werden unter Ubuntu nicht so gut unterstützt, und Sie müssen durch die Rahmen gehen, um ein Gebietsschema mit diesen zu generieren, und wenn Sie dies tun, werden Sie feststellen, dass viele Dinge nicht funktionieren richtig arbeiten.
In Ubuntu sind Zeichensätze entweder Einzelbyte- oder UTF-8-Zeichensätze.
Nun noch ein paar Anmerkungen:
In UTF-8 bilden nicht alle Bytefolgen gültige Zeichen. Beispielsweise werden alle UTF-8-Zeichen, die keine ASCII-Zeichen sind, mit Bytes gebildet, für die das 8. Bit gesetzt ist, für die jedoch nur für das erste das 7. Bit gesetzt ist.
Wenn Sie eine Folge von Bytes mit dem 8. Bit gesetzt haben, von denen keines das 7. Bit gesetzt hat, kann dies nicht in ein Zeichen übersetzt werden. Und dann treten Probleme und Inkonsistenzen auf, da die Software nicht weiß, was sie damit anfangen soll. Zum Beispiel:
wc
undgrep
finde keinen Charakter darin aber:bash
Findet 3. Wenn einem Zeichen keine Folge von Bytes zugeordnet werden kann, wird jedes Byte als Zeichen betrachtet.Dies kann noch komplizierter werden, da es in Unicode Codepunkte gibt, die als Zeichen ungültig sind, und einige, die keine Zeichen sind. Je nach Tool wird die UTF-8-Codierung möglicherweise als Zeichen betrachtet oder nicht.
Eine andere zu berücksichtigende Sache ist der Unterschied zwischen Charakter und Graphem und wie sie gerendert werden.
Dort haben wir 3 Zeichen als 6 Bytes als ein Graphem gerendert, weil wir 3 Zeichen zusammen haben (ein Basiszeichen, einen kombinierenden Akzent und einen kombinierenden umschließenden Kreis).
Die GNU-Implementierung von
wc
as, wie sie unter Ubuntu zu finden ist, verfügt über einen-L
Schalter, der die Anzeigebreite der breitesten Zeile in der Eingabe angibt:Sie werden auch feststellen, dass einige Zeichen in dieser Breitenberechnung 2 Zellen belegen , wie unser
乕
Zeichen von oben:Fazit: Im wilden Wort sind Byte, Zeichen und Graphem nicht unbedingt dasselbe.
quelle
Der Unterschied zwischen
wc -c
undwc -m
besteht darin, dass in einem Gebietsschema mit Multibyte-Zeichen (z. B. UTF8) das erste Byte zählt, während das zweite Zeichen zählt. Betrachten Sie die folgende Datei:(Für diejenigen, die kein UTF8 sprechen, sind das die Buchstaben 'x', 'y' und 'π', gefolgt von einer neuen Zeile). Es ist fünf Bytes lang:
aber nur vier Zeichen lang:
quelle