Wenn Sie dies tun und die benötigten Leerzeichen entfernen möchten:
echo -n "Hello" | od -A n -t x1 | sed 's/ *//g'
Die ersten beiden Befehle in der Pipeline werden von @TMS in seiner Antwort, bearbeitet von @James, gut erklärt. Der letzte Befehl unterscheidet sich vom @TMS-Kommentar dadurch, dass er sowohl korrekt ist als auch getestet wurde. Die Erklärung lautet:
sedist ein s behandeln ed itor.sist das s Befehl ersetzen./öffnet einen regulären Ausdruck - jedes beliebige Zeichen kann verwendet werden./ist konventionell, aber umständlich für die Verarbeitung von beispielsweise XML oder Pfadnamen./oder das von Ihnen gewählte Alternativzeichen schließt den regulären Ausdruck und öffnet die Substitutionszeichenfolge.- In
/ */die*entspricht einer beliebigen Folge des vorherigen Zeichens (in diesem Fall ein Leerzeichen). /oder das von Ihnen gewählte alternative Zeichen schließt die Substitutionszeichenfolge. In diesem Fall die Substitutionszeichenfolge//ist leer, d.h. der Treffer wird gelöscht.gist die Option, diese Ersetzung g vorzunehmen global auf jeder Zeile statt nur einmal für jede Zeile.- Die Anführungszeichen verhindern, dass der Befehlsparser verwirrt wird - die gesamte Sequenz wird an
sedübergeben als erste Option, nämlich einesedSkript.
@TMS-Gehirnkind (sed 's/^ *//' ) entfernt nur Leerzeichen am Anfang jeder Zeile (^ entspricht dem Anfang der Zeile - 'Musterraum' in sed -sprechen).
Wenn Sie zusätzlich Zeilenumbrüche entfernen möchten, ist der einfachste Weg das Anhängen
| tr -d '\n'
zu den Befehlspfeifen. Es funktioniert wie folgt:
|speist den zuvor verarbeiteten Stream in die Standardeingabe dieses Befehls ein.trist das tr anslate-Befehl.-dgibt das Löschen der Übereinstimmungszeichen an.- Anführungszeichen listen Ihre übereinstimmenden Zeichen auf - in diesem Fall nur Zeilenumbruch (
\n).Translate passt nur auf einzelne Zeichen, nicht auf Sequenzen.
sed ist eindeutig verzögert, wenn es um Zeilenumbrüche geht. Das liegt daran, dass sed ist einer der ältesten unix Befehle - es wurde erstellt, bevor die Leute wirklich wussten, was sie taten. Allgegenwärtige Legacy-Software verhindert, dass es behoben wird. Ich weiß das, weil ich vor unix geboren wurde wurde geboren.
Der historische Ursprung des Problems war die Idee, dass ein Zeilenumbruch ein Zeilentrennzeichen und kein Teil der Zeile sei. Es wurde daher von den Zeilenverarbeitungsdienstprogrammen entfernt und von den Ausgabedienstprogrammen wieder eingefügt. Das Problem ist, dass dies Annahmen über die Struktur von Benutzerdaten macht und in vielen Einstellungen unnatürliche Einschränkungen auferlegt. sed Die Unfähigkeit von , Zeilenumbrüche einfach zu entfernen, ist eines der häufigsten Beispiele für diese missgebildete Ideologie, die Kummer verursacht.
Es ist möglich, Zeilenumbrüche mit sed zu entfernen - Es ist nur so, dass alle mir bekannten Lösungen sed ergeben Verarbeiten Sie die gesamte Datei auf einmal, was bei sehr großen Dateien zu Engpässen führt und den Zweck eines Stream-Editors zunichte macht. Jede Lösung, die die Zeilenverarbeitung beibehält, wenn es möglich ist, wäre ein unlesbares Rattennest aus mehreren Pipes.
Wenn Sie darauf bestehen, sed zu verwenden versuche:
sed -z 's/\n//g'
-z sagt sed um Nullen als Zeilentrennzeichen zu verwenden.
Intern ein String in C wird mit einer Null abgeschlossen. Der -z Die Option ist auch ein Ergebnis von Legacy und wird als Annehmlichkeit für C bereitgestellt Programmierer, die vielleicht eine temporäre Datei verwenden möchten, die mit C gefüllt ist -Strings und aufgeräumt durch Zeilenumbrüche. Sie können dann problemlos jeweils eine Zeichenfolge lesen und verarbeiten. Auch hier erlegen die frühen Annahmen über Anwendungsfälle den Benutzerdaten künstliche Beschränkungen auf.
Wenn Sie den g weglassen Option entfernt dieser Befehl nur den ersten Zeilenumbruch. Mit dem -z Option sed interpretiert die gesamte Datei als eine Zeile (es sei denn, es sind vereinzelte Nullen in der Datei eingebettet), die durch eine Null abgeschlossen werden und daher auch große Dateien verstopfen.
Sie denken vielleicht
sed 's/^/\x00/' | sed -z 's/\n//' | sed 's/\x00//'
könnte funktionieren. Der erste Befehl setzt zeilenweise eine Null an den Anfang jeder Zeile, was zu \n\x00 führt jede Zeile beenden. Der zweite Befehl entfernt einen Zeilenumbruch aus jeder Zeile, die jetzt durch Nullen getrennt ist - aufgrund des ersten Befehls gibt es nur einen Zeilenumbruch. Alles, was übrig bleibt, sind die falschen Nullen. So weit, ist es gut. Die kaputte Idee dabei ist, dass die Pipe den letzten Befehl zeilenweise füttert, da der Stream so aufgebaut wurde. Tatsächlich wird der letzte Befehl, wie geschrieben, nur eine Null entfernen, da jetzt die gesamte Datei keine Zeilenumbrüche hat und daher eine Zeile ist.
Eine einfache Pipe-Implementierung verwendet eine temporäre Zwischendatei, und alle Eingaben werden verarbeitet und in die Datei eingespeist. Der nächste Befehl wird möglicherweise in einem anderen Thread ausgeführt und liest gleichzeitig diese Datei, aber er sieht nur den Stream als Ganzes (wenn auch unvollständig) und hat keine Kenntnis von den Chunk-Grenzen, die die Datei speisen. Selbst wenn die Pipe ein Speicherpuffer ist, sieht der nächste Befehl den Stream als Ganzes. Der Fehler ist untrennbar in sed eingebrannt .
Damit dieser Ansatz funktioniert, benötigen Sie einen g Option beim letzten Befehl, also verschluckt es sich wieder bei großen Dateien.
Die Quintessenz lautet:Verwenden Sie sed nicht um Zeilenumbrüche zu verarbeiten.
echo hello | hexdump -v -e '/1 "%02X "'
echo -n "Hello" | od -A n -t x1
Erklärung:
- Der
echoDas Programm liefert die Zeichenkette für den nächsten Befehl. - Der
-nFlag weist Echo an, keine neue Zeile am Ende des „Hallo“ zu erzeugen. - Der
odProgramm ist das "Octal-Dump"-Programm. (Wir werden ein Flag bereitstellen, um es anzuweisen, es im Hexadezimalformat statt im Oktalformat auszugeben.) - Der
-A nFlag ist die Abkürzung für--address-radix=n, wobei n die Abkürzung für "none" ist. Ohne diesen Teil würde der Befehl auf der linken Seite ein hässliches numerisches Adresspräfix ausgeben. Dies ist nützlich für große Dumps, aber für einen kurzen String ist es unnötig. - Der
-t x1Flag ist die Abkürzung für--format=x1, wobei das x die Abkürzung für "hexadezimal" und die 1 für 1 Byte steht.