Um die Tour durch diese nicht so bekannten Befehle fortzusetzen, die letzte Woche mit dem Befehl ls begonnen wurde, wollen wir uns heute die cat
ansehen Befehl.
Die Katze
name steht für catenate
da die Hauptaufgabe dieses Befehls darin besteht, mehrere Eingabedateien zu verbinden, indem deren Inhalt nacheinander an die Standardausgabe gesendet wird:
# Let's obtain first some sample data files:
curl -so - dict://dict.org/'d:felidae:gcide' | unexpand -a -t 3 |
sed -Ee '/^151/,/^[.]/!d;/^[.0-9]/s/.*//' > felidae.txt
curl -so - dict://dict.org/'d:felis:gcide' | unexpand -a -t 3 |
sed -Ee '/^151/,/^[.]/!d;/^[.0-9]/s/.*//' > felis.txt
# Catenate files
cat felidae.txt felis.txt
Wenn Sie das Ergebnis dieser Verkettung in einer Datei speichern möchten, müssen Sie eine Shell-Umleitung verwenden:
cat felidae.txt felis.txt > result.txt
cat result.txt
Auch wenn sein primäres Designziel darin besteht, Dateien zu verketten, ist die cat
wird auch oft mit nur einem Argument verwendet, um den Inhalt dieser Datei auf dem Bildschirm anzuzeigen, genau wie ich es in der letzten Zeile des obigen Beispiels getan habe.
A. Cat-Befehl mit Standardeingabe verwenden
Bei Verwendung ohne Argument wird die cat
Der Befehl liest Daten von seiner Standardeingabe und schreibt sie in seine Standardausgabe – was meistens nutzlos ist … es sei denn, Sie verwenden eine Option, um die Daten umzuwandeln. Wir werden später über ein paar interessante Optionen sprechen.
Zusätzlich zu den Dateipfaden wird die Datei cat
Der Befehl versteht auch den -
spezieller Dateiname als Alias für die Standardeingabe. Auf diese Weise können Sie die von der Standardeingabe gelesenen Daten zwischen die auf der Befehlszeile angegebenen Dateien einfügen:
# Insert a separator between the two concatenated files
echo '----' | cat felis.txt - felidae.txt
B. Verwendung des cat-Befehls mit Binärdateien
1. Geteilte Dateien zusammenfügen
Die Katze
Der Befehl macht keine Annahmen über den Dateiinhalt und funktioniert daher problemlos mit Binärdaten. Etwas, das nützlich sein kann, um Dateien, die durch den split
beschädigt wurden, wieder zusammenzuführen oder csplit
Befehl. Oder um Teildownloads beizutreten, wie wir es jetzt tun werden:
#
# A picture by Von.grzanka (CC-SA 3.0)
# Optimize bandwidth usage by breaking the download in two parts
# (on my system, I observe a 10% gain that way compared to a "full" download)
curl -s -r 0-50000 \
https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Felis_catus-cat_on_snow.jpg/1024px-Felis_catus-cat_on_snow.jpg \
-o first-half &
curl -s -r 50001- \
https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Felis_catus-cat_on_snow.jpg/1024px-Felis_catus-cat_on_snow.jpg \
-o second-half &
wait
Wir haben jetzt zwei Hälften eines Bildes. Sie können die erste Hälfte öffnen und sehen, dass sie „kaputt“ ist, indem Sie die Anzeige
von ImageMagick verwenden , oder gimp
, oder jede andere Software, die Bilddateien lesen kann:
display first-half
# -or-
gimp first-half
# -or-
firefox first-half
Wenn Sie die Curl
studieren Befehl, den ich verwendet habe, sehen Sie, dass sich die beiden Teile perfekt ergänzen. Die erste Hälfte geht von Byte 0 bis 50000 und die zweite Hälfte von Byte 50001 bis zum Ende der Datei. Dazwischen sollten keine Daten fehlen. Wir müssen also nur die beiden Teile miteinander verketten (in der richtigen Reihenfolge), um die vollständige Datei zurückzubekommen:
cat first-half second-half > image.jpg
display image.jpg
2. Arbeiten mit streamfähigen Dateiformaten
Nicht nur Sie können die Katze
verwenden Befehl, Binärdateien, die in mehrere Teile aufgeteilt wurden, „wieder zusammenzufügen“, aber in einigen Fällen können Sie auch neue erstellen Dateien auf diese Weise. Das funktioniert besonders gut mit „headerlosen“ oder „streambaren“ Dateiformaten wie MPEG-Transportstream-Videodateien (.TS
Dateien):
# Let's make a still video file from our picture
ffmpeg -y -loop 1 -i cat.jpg -t 3 \
-c:v libx264 -vf scale=w=800:h=-1 \
still.ts
# Let's make a fade-in from the same picture
ffmpeg -y -loop 1 -i cat.jpg -t 3 \
-c:v libx264 -vf scale=w=800:h=-1,fade=in:0:75 \
fadein.ts
# Let's make a fade-out from the same picture
ffmpeg -y -loop 1 -i cat.jpg -t 3 \
-c:v libx264 -vf scale=w=800:h=-1,fade=out:0:75 \
fadeout.ts
Wir können jetzt all diese Transportstream-Videodateien mit dem cat
kombinieren Befehl, wodurch eine vollkommen gültige TS-Datei in der Ausgabe erhalten wird:
cat fadein.ts still.ts fadeout.ts > video.ts
mplayer video.ts
Dank des TS-Dateiformats können Sie diese Dateien in der gewünschten Reihenfolge kombinieren und sogar dieselbe Datei mehrmals in der Argumentliste verwenden, um Schleifen oder Wiederholungen im Ausgabevideo zu erstellen. Natürlich würde das mehr Spaß machen, wenn wir animierte Bilder verwenden würden, aber ich lasse Sie das selbst tun:Viele Verbrauchergeräte zeichnen TS-Dateien auf, und wenn sie dies nicht tun, können Sie immer noch ffmpeg um fast jede Videodatei in eine Transportstromdatei umzuwandeln. Zögern Sie nicht, Ihre Kreationen im Kommentarbereich zu teilen!
3. cpio-Archive hacken
Lassen Sie uns als letztes Beispiel sehen, wie wir cat
verwenden können Befehl zum Kombinieren mehrerer cpio
Archiv. Aber dieses Mal wird es nicht so einfach sein, da es ein wenig Wissen über cpio
erfordert Archivdateiformat.
Ein cpio
archive speichert die Metadaten und den Inhalt der Datei sequentiell, wodurch es für die Verkettung auf Dateiebene mit cat
geeignet ist Nützlichkeit. Leider ist der cpio
Archiv enthält auch einen Trailer, der verwendet wird, um das Ende des Archivs zu markieren:
# Create two genuine CPIO `bin` archive:
$ find felis.txt felidae.txt | cpio -o > part1.cpio
2 blocks
$ echo cat.jpg | cpio -o > part2.cpio
238 blocks
$ hexdump -C part1.cpio | tail -7
000002d0 2e 0d 0a 09 09 20 20 5b 57 6f 72 64 4e 65 74 20 |..... [WordNet |
000002e0 31 2e 35 5d 0d 0a 0a 00 c7 71 00 00 00 00 00 00 |1.5].....q......|
000002f0 00 00 00 00 01 00 00 00 00 00 00 00 0b 00 00 00 |................|
00000300 00 00 54 52 41 49 4c 45 52 21 21 21 00 00 00 00 |..TRAILER!!!....|
00000310 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000400
$ hexdump -C part2.cpio | tail -7
0001da40 46 96 ab f8 ad 11 23 90 32 79 ac 1f 8f ff d9 00 |F.....#.2y......|
0001da50 c7 71 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |.q..............|
0001da60 00 00 00 00 0b 00 00 00 00 00 54 52 41 49 4c 45 |..........TRAILE|
0001da70 52 21 21 21 00 00 00 00 00 00 00 00 00 00 00 00 |R!!!............|
0001da80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
0001dc00
Die gute Neuigkeit ist, dass Trailer bei cpio-Binärarchiven eine feste Länge von 280 Bytes haben. Verwenden Sie also den head
Standardbefehl haben wir eine einfache Möglichkeit, es zu entfernen:
# Each archive end with the 280-byte trailer.
# To catenate both archives, just remove the trailer
# at the end of the first part:
$ head -c-280 part1.cpio | cat - part2.cpio > cat.cpio
$ cpio -it < cat.cpio
felis.txt
felidae.txt
cat.jpg
239 blocks
C. Grundlegende cat-Befehlsoptionen
Nachdem wir mit verschiedenen binären Dateiformaten gespielt haben, kehren wir jetzt zu einfachen alten Textdateien zurück, indem wir einige Optionen untersuchen, die speziell auf diese Dateien zugeschnitten sind. Obwohl sie nicht Teil des POSIX-Standards sind, sind diese Optionen über BSD und GNU cat
portierbar Implementierungen. Bitte beachten Sie, dass ich hier nicht vorgebe, erschöpfend zu sein, also überprüfen Sie den man
um die vollständige Liste der von cat
unterstützten Optionen anzuzeigen auf Ihrem System!
-n
:Zahlenzeilen
Mit dem n
Option, die cat
Befehl wird jeder Ausgabezeile ihre Zeilennummer vorangestellt:
cat -n felidae.txt
1
2 Felidae \Felidae\ n.
3 a natural family of lithe-bodied round-headed fissiped
4 mammals, including the cats; wildcats; lions; leopards;
5 cheetahs; and saber-toothed tigers.
6
7 Syn: family {Felidae}.
8 [WordNet 1.5]
9
Das -n
Optionsnummern Ausgabe Linien. Das heißt, der Zähler ist nicht zurückgesetzt, wenn von einer Eingabedatei zur nächsten gewechselt wird, wie Sie es sehen werden, wenn Sie den folgenden Befehl selbst ausprobieren:
cat -n feli*.txt
-s
:wiederholte leere Ausgabezeilen unterdrücken
Mit dem -s
Option, die cat
Der Befehl reduziert mehrere aufeinanderfolgende leere Zeilen in nur einer:
cat -n felis.txt felidae.txt | sed -n 8,13p
8 lynx ({Felis lynx}) is also called {Lynx lynx}.
9 [1913 Webster +PJC]
10
11
12 Felidae \Felidae\ n.
13 a natural family of lithe-bodied round-headed fissiped
[email protected]:~$ cat -ns felis.txt felidae.txt | sed -n 8,13p
8 lynx ({Felis lynx}) is also called {Lynx lynx}.
9 [1913 Webster +PJC]
10
11 Felidae \Felidae\ n.
12 a natural family of lithe-bodied round-headed fissiped
13 mammals, including the cats; wildcats; lions; leopards;
Im obigen Beispiel sehen Sie, dass in der Standardausgabe die Zeilen 10 und 11 leer waren. Beim Hinzufügen des -s
Option wurde die zweite Leerzeile verworfen.
-b
:Nur nicht leere Zeilen nummerieren
Etwas verwandt mit den beiden vorangehenden Optionen, dem -b
Option nummeriert Zeilen, ignoriert aber leere Zeilen:
$ cat -b felidae.txt | cat -n
1
2 1 Felidae \Felidae\ n.
3 2 a natural family of lithe-bodied round-headed fissiped
4 3 mammals, including the cats; wildcats; lions; leopards;
5 4 cheetahs; and saber-toothed tigers.
6 5
7 6 Syn: family {Felidae}.
8 7 [WordNet 1.5]
9
Das obige Beispiel verwendet zwei Instanzen von cat
Befehl mit verschiedenen Optionen in einer Pipeline. Die innere Nummerierung kommt vom -b
Option, die mit dem ersten cat
verwendet wird Befehl. Die äußere Nummerierung ergibt sich aus dem -n
Option, die mit der zweiten cat
verwendet wird .
Wie Sie sehen können, waren die erste und letzte Zeile nicht nummeriert durch das -b
Option, weil sie leer sind. Aber was ist mit der 6. Zeile? Warum wird es immer noch mit dem -b
nummeriert? Möglichkeit? Nun, weil es ein Leerzeichen ist line— aber kein leer eine, wie wir im nächsten Abschnitt sehen werden.
-v
, -e
, -t
:nicht druckbare Zeichen anzeigen
Die drei Optionen -v
, -e ` und `-t
werden verwendet, um verschiedene Sätze unsichtbarer Zeichen anzuzeigen. Auch wenn sich die Sets überschneiden, gibt es keine „Alles-auffangen“-Option, sodass Sie sie kombinieren müssen, wenn Sie alle anzeigen möchten unsichtbare Zeichen.
-v
:Unsichtbare Zeichen anzeigen
Das -v
Option zeigt alle nicht druckbaren Zeichen mit Caret und Meta-Notation an, außer den Zeilenvorschub und die Tabellierung.
Mit dieser Option erscheinen Steuerzeichen als Caretzeichen (^
) gefolgt vom entsprechenden ASCII-Zeichen (z. B. wird der Wagenrücklauf, Byte 13, als ^M
angezeigt weil M
in ASCII ist 64 + 13), und Zeichen mit gesetztem höherwertigem Bit erscheinen in der „Meta“-Notation M-
gefolgt von der Darstellung, die den 7 unteren Bits entspricht (z. B. wird das Byte 141 als M-^M
angezeigt denn 141 ist 128 + 13).
Obwohl es scheinbar esoterisch erscheint, kann diese Funktion nützlich sein, wenn Sie mit Binärdateien arbeiten, wie zum Beispiel, wenn Sie die in eine JPEG-Datei eingebetteten Rohinformationen untersuchen möchten:
$ cat -v cat.jpg | fold -75 | head -10
M-^?M-XM-^?M-`^@^PJFIF^@^A^A^A^@H^@H^@^@M-^?M-~^@QFile source: http://commo
ns.wikimedia.org/wiki/File:Felis_catus-cat_on_snow.jpgM-^?M-b^LXICC_PROFILE
^@^A^A^@^@^LHLino^B^P^@^@mntrRGB XYZ ^GM-N^@^B^@ ^@^F^@1^@^@acspMSFT
^@^@^@^@IEC sRGB^@^@^@^@^@^@^@^@^@^@^@^@^@^@M-vM-V^@^A^@^@^@^@M-S-HP ^@^@^
@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
^@^@^@^@^@^@^@^Qcprt^@^@^AP^@^@^@3desc^@^@^AM-^D^@^@^@lwtpt^@^@^AM-p^@^@^@^
Tbkpt^@^@^B^D^@^@^@^TrXYZ^@^@^B^X^@^@^@^TgXYZ^@^@^B,^@^@^@^TbXYZ^@^@^[email protected]^@^@
^@^Tdmnd^@^@^BT^@^@^@pdmdd^@^@^BM-D^@^@^@M-^Hvued^@^@^CL^@^@^@M-^Fview^@^@^
CM-T^@^@^@$lumi^@^@^CM-x^@^@^@^Tmeas^@^@^D^L^@^@^@$tech^@^@^D0^@^@^@^LrTRC^
@^@^D<^@^@^H^LgTRC^@^@^D<^@^@^H^LbTRC^@^@^D<^@^@^H^Ltext^@^@^@^@Copyright (
Ein weiterer Anwendungsfall für -v
Option ist das Auffinden von Steuerzeichen, die möglicherweise in eine Textdatei gelangt sind. Wenn Sie sich daran erinnern, haben wir dieses seltsame Problem oben mit dem -b
Option, die die 6. Eingabezeile nummeriert, während es aussah als wäre es leer. Untersuchen wir das also:
$ cat -v felidae.txt
Felidae \Felidae\ n.^M
a natural family of lithe-bodied round-headed fissiped^M
mammals, including the cats; wildcats; lions; leopards;^M
cheetahs; and saber-toothed tigers.^M
^M
Syn: family {Felidae}.^M
[WordNet 1.5]^M
Ah ah! Sehen Sie diese ^M
Marken? Sie werden verwendet, um das ansonsten unsichtbare Carriage-Return-Zeichen zu ersetzen. Woher kam das? Nun, das dict
Das Protokoll verwendet wie jedes andere Internetprotokoll CRLF als Zeilenabschluss. Also haben wir sie als Teil unserer Beispieldateien heruntergeladen. Mehr über Zeilenvorschub und Wagenrücklauf erfahren Sie im Fold
und fmt
Artikel. Aber jetzt erklärt es, warum cat
betrachtet die 6. Zeile als nicht leer.
-e
:unsichtbare Zeichen anzeigen, einschließlich Zeilenende
Das -e
Option funktioniert wie -v
Option, außer dass auch ein Dollarzeichen hinzugefügt wird ($
) vor jedem Zeilenvorschubzeichen, wodurch das Zeilenende explizit angezeigt wird:
$ cat -e felidae.txt
$
Felidae \Felidae\ n.^M$
a natural family of lithe-bodied round-headed fissiped^M$
mammals, including the cats; wildcats; lions; leopards;^M$
cheetahs; and saber-toothed tigers.^M$
^M$
Syn: family {Felidae}.^M$
[WordNet 1.5]^M$
$
-t
:unsichtbare Zeichen anzeigen, einschließlich Tabulatoren
Das -t
Option funktioniert wie -v
Option, außer dass es auch Tabellen mit ^I
anzeigt Caret-Notation (Tabulator wird als Byte gespeichert, das den Wert 9 enthält, und I
in ASCII ist 64+9=73):
$ cat -t felidae.txt
Felidae \Felidae\ n.^M
^Ia natural family of lithe-bodied round-headed fissiped^M
^Imammals, including the cats; wildcats; lions; leopards;^M
^Icheetahs; and saber-toothed tigers.^M
^M
^ISyn: family {Felidae}.^M
^I^I [WordNet 1.5]^M
-et
:alle versteckten Zeichen anzeigen
Wie ich bereits kurz erwähnt habe, müssen Sie, wenn Sie alle nicht druckbaren Zeichen anzeigen möchten, einschließlich Tabulatoren und Zeilenende-Markierungen, beides verwenden:-e
und -t
Optionen:
$ cat -et felidae.txt
$
Felidae \Felidae\ n.^M$
^Ia natural family of lithe-bodied round-headed fissiped^M$
^Imammals, including the cats; wildcats; lions; leopards;^M$
^Icheetahs; and saber-toothed tigers.^M$
^M$
^ISyn: family {Felidae}.^M$
^I^I [WordNet 1.5]^M$
$
Bonus:Die nutzlose Verwendung des cat-Befehls in Linux
Kein Artikel über die Katze
Der Befehl wäre ohne eine Erwähnung des Anti-Patterns „Useless Use of Cat“ vollständig.
Es tritt auf, wenn Sie cat
verwenden für den einzigen Zweck, den Inhalt einer Datei an die Standardeingabe eines anderen Befehls zu senden. Diese Verwendung der cat
Der Befehl wird als „nutzlos“ bezeichnet, da eine einfache Umleitung oder ein Dateinamenparameter die Aufgabe erledigt hätte und es besser gemacht hätte. Aber ein Beispiel sagt mehr als tausend Worte:
$ curl -so - dict://dict.org/'d:uuoc:jargon' | sed -Ee '/^151/,/^[.]/!d;/^[.0-9]/s/.*//' > uuoc.txt
$ cat uuoc.txt | less
UUOC
[from the comp.unix.shell group on Usenet] Stands for Useless Use of {cat};
the reference is to the Unix command cat(1), not the feline animal. As
received wisdom on comp.unix.shell observes, ?The purpose of cat is to
concatenate (or ?catenate?) files. If it's only one file, concatenating it
with nothing at all is a waste of time, and costs you a process.?
Nevertheless one sees people doing
cat file | some_command and its args ...
instead of the equivalent and cheaper
<file some_command and its args ...
or (equivalently and more classically)
some_command and its args ... <file
[...]
Im obigen Beispiel habe ich eine Pipeline verwendet, um den Inhalt der uuoc.txt
anzuzeigen Datei mit dem weniger
Pager:
cat uuoc.txt | less
Also der einzige Zweck der cat
Befehl war, die Standardeingabe des less
zu füttern Befehl mit dem Inhalt der uuoc.txt
Datei. Ich hätte das gleiche Verhalten mit einer Shell-Umleitung erhalten:
less < uuoc.txt
In der Tat, die weniger
Der Befehl akzeptiert wie viele Befehle auch einen Dateinamen als Argument. Also hätte ich stattdessen einfach schreiben können:
less uuoc.txt
Wie Sie sehen können, ist cat
nicht erforderlich hier. Wenn ich das Anti-Pattern „Useless Use of Cat“ erwähne, liegt das daran, dass Sie, wenn Sie es öffentlich in einem Forum oder anderswo verwenden, zweifellos jemand mit dem Argument darauf hinweisen wird, dass Sie einen „zusätzlichen Prozess für nichts“ erstellen würden. ”
Ich muss zugeben, dass ich solche Kommentare lange Zeit ziemlich abschätzig behandelt habe. Schließlich kann auf unserer modernen Hardware das Erzeugen eines zusätzlichen Prozesses für einen One-Shot-Vorgang nicht so viel Overhead verursachen.
Aber während ich diesen Artikel schrieb, habe ich ein schnelles Experiment durchgeführt und die benötigte Zeit mit und ohne UUOC durch ein Test-awk
verglichen Skript zum Verarbeiten von 500 MB Daten von einem langsamen Medium.
Zu meiner Überraschung war der Unterschied alles andere als vernachlässigbar:
Der Grund liegt jedoch nicht darin, dass ein zusätzlicher Prozess erstellt wird. Aber wegen des zusätzlichen Lesens/Schreibens und Kontextwechsels entsteht das UUOC (wie Sie es aus der Zeit ableiten können, die für die Ausführung von Systemcode aufgewendet wird). Also tatsächlich, wenn Sie an großen Datenmengen arbeiten, diese zusätzliche Katze
Befehl hat nicht unerhebliche Kosten. Was mich betrifft, werde ich versuchen, jetzt wachsamer damit umzugehen! Und du? Wenn Sie Beispiele für die nutzlose Verwendung von Cat haben, zögern Sie nicht, sie mit uns zu teilen!