Pokračujeme v prohlídce těch nepříliš známých příkazů zahájených minulý týden příkazem ls, dnes se podíváme na cat
příkaz.
kočka
název znamená catenate
protože primární úlohou tohoto příkazu je spojit několik vstupních souborů postupným odesláním jejich obsahu na standardní výstup:
# 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
Pokud chcete uložit výsledek tohoto zřetězení do souboru, musíte použít přesměrování shellu:
cat felidae.txt felis.txt > result.txt
cat result.txt
I když je jeho primárním cílem návrhu řetězit soubory, cat
obslužný program se také často používá pouze s jedním argumentem pro zobrazení obsahu tohoto souboru na obrazovce, přesně jako jsem to udělal na posledním řádku výše uvedeného příkladu.
A. Použití příkazu cat se standardním vstupem
Při použití bez jakéhokoli argumentu cat
příkaz načte data ze svého standardního vstupu a zapíše je na svůj standardní výstup – což je většinou k ničemu… pokud nepoužíváte nějakou možnost transformace dat. O několika zajímavých možnostech si povíme později.
Kromě cest k souboru, cat
příkaz také rozumí -
speciální název souboru jako alias pro standardní vstup. Tímto způsobem můžete vložit data načtená ze standardního vstupu mezi soubory uvedené na příkazovém řádku:
# Insert a separator between the two concatenated files
echo '----' | cat felis.txt - felidae.txt
B. Použití příkazu cat s binárními soubory
1. Spojení rozdělených souborů
kočka
příkaz nevytváří žádné předpoklady o obsahu souboru, takže bude vesele pracovat s binárními daty. Něco, co může být užitečné pro opětovné spojení souborů poškozených rozdělením
nebo csplit
příkaz. Nebo se připojit k částečným stahováním, jako to uděláme teď:
#
# 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
Nyní máme dvě poloviny obrázku. Můžete otevřít první polovinu a vidět, že je „rozbitá“ pomocí displeje
ImageMagick nebo gimp
, nebo jakýkoli jiný software schopný číst soubory obrázků:
display first-half
# -or-
gimp first-half
# -or-
firefox first-half
Pokud si prostudujete curl
příkaz, který jsem použil, vidíte, že se obě části dokonale doplňují. První polovina je od bajtu 0 do 50 000 a druhá polovina od bajtu 50 001 do konce souboru. Mezi nimi by neměla chybět žádná data. Musíme tedy pouze spojit dvě části dohromady (ve správném pořadí), abychom získali zpět celý soubor:
cat first-half second-half > image.jpg
display image.jpg
2. Práce se streamovatelnými formáty souborů
Nejen vy můžete použít cat
příkaz „znovu připojit“ binární soubory, které byly rozděleny do několika částí, ale v některých případech můžete také vytvořit nové soubory tímto způsobem. To funguje zvláště dobře s „headerless“ nebo „streamovatelnými“ formáty souborů, jako jsou MPEG transportní video soubory (.TS
soubory):
# 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
Nyní můžeme kombinovat všechny tyto video soubory transportního toku pomocí cat
příkaz, získání dokonale platného souboru TS ve výstupu:
cat fadein.ts still.ts fadeout.ts > video.ts
mplayer video.ts
Díky formátu souboru TS můžete tyto soubory kombinovat v požadovaném pořadí a dokonce můžete stejný soubor použít několikrát v seznamu argumentů k vytvoření smyček nebo opakování ve výstupním videu. Samozřejmě by to bylo zábavnější, kdybychom používali animované obrázky, ale nechám vás to udělat sami:mnoho zařízení pro spotřebitele zaznamenává soubory TS, a pokud ne, můžete stále používat ffmpeg převést téměř jakýkoli video soubor na soubor transportního toku. Neváhejte a podělte se o své výtvory pomocí sekce komentářů!
3. Hackování archivů cpio
Jako poslední příklad se podívejme, jak můžeme použít cat
příkaz ke kombinaci několika cpio
archiv. Ale tentokrát to nebude tak jednoduché, protože to bude vyžadovat trochu znalostí o cpio
formát archivního souboru.
cpio
archiv ukládá metadata a obsah souboru postupně, takže je vhodný pro zřetězení na úrovni souboru s cat
užitečnost. Bohužel, cpio
archiv také obsahuje upoutávku používanou k označení konce archivu:
# 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
Dobrou novinkou je, že u binárních archivů cpio má upoutávka pevnou délku 280 bajtů. Takže pomocí head
standardní příkaz, máme snadný způsob, jak jej odstranit:
# 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. Základní možnosti příkazu cat
Poté, co jsme si pohráli s různými formáty binárních souborů, vraťme se nyní k obyčejným starým textovým souborům tím, že si prostudujeme několik možností, které jsou speciálně přizpůsobeny pro práci s těmito soubory. I když nejsou součástí standardu POSIX, jsou tyto možnosti přenosné napříč BSD a GNU cat
implementací. Vezměte prosím na vědomí, že zde nepředstírám, že jsem vyčerpávající, takže zkontrolujte man
zobrazíte úplný seznam možností podporovaných cat
ve vašem systému!
-n
:číselné řady
Pomocí n
možnost, cat
příkaz předpíše každému výstupnímu řádku jeho číslo řádku:
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
-n
čísla možností výstup linky. To znamená, že počítadlo není reset při přepínání z jednoho vstupního souboru na druhý, jak to uvidíte, když sami vyzkoušíte následující příkaz:
cat -n feli*.txt
-s
:potlačit opakované prázdné výstupní řádky
Pomocí -s
možnost, cat
příkaz sbalí několik po sobě jdoucích prázdných řádků pouze do jednoho:
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;
Ve výše uvedeném příkladu můžete vidět, že ve výchozím výstupu byly řádky 10 a 11 prázdné. Při přidávání -s
možnost, druhý prázdný řádek byl zahozen.
-b
:číslujte pouze neprázdné řádky
Poněkud souvisí se dvěma předchozími možnostmi, -b
volba bude číslovat řádky, ale ignorovat prázdné:
$ 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
Výše uvedený příklad používá dvě instance cat
příkaz s různými možnostmi v potrubí. Vnitřní číslování pochází z -b
možnost použitá s první cat
příkaz. Vnější číslování pochází z -n
možnost použitá s druhým cat
.
Jak vidíte, první a poslední řádek ne byly číslovaný -b
možnost, protože jsou prázdné. Ale co ten 6. řádek? Proč je stále číslováno -b
volba? Protože je to prázdné řádek — ale ne prázdný jeden, jak uvidíme v další části.
-v
, -e
, -t
:zobrazení netisknutelných znaků
Tři možnosti -v
, -e ` a `-t
se používají k zobrazení různých sad neviditelných znaků. I když se sady překrývají, neexistuje možnost „catch-all“, takže pokud chcete zobrazit všechny, budete je muset zkombinovat neviditelné znaky.
-v
:zobrazení neviditelných znaků
-v
možnost zobrazit všechny netisknutelné znaky s stříškou a meta notací, kromě posun řádku a tabelaci.
S touto možností se řídicí znaky zobrazí jako stříška (^
) následovaný příslušným znakem ASCII (např. návrat vozíku, bajt 13, se zobrazí jako ^M
protože M
v ASCII je 64 + 13) a znaky s nastaveným bitem vyššího řádu se objeví v „meta“ notaci M-
následuje reprezentace odpovídající 7 nižším bitům (např. bajt 141 bude zobrazen jako M-^M
protože 141 je 128 + 13).
I když se tato funkce zdá být esoterická, může být užitečná při práci s binárními soubory, například pokud chcete prozkoumat nezpracované informace vložené do souboru JPEG:
$ 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 (
Další případ použití pro -v
možností je najít řídicí znaky, které mohly uniknout do textového souboru. Pokud si to pamatujete, máme výše uvedený podivný problém s -b
možnost číslování 6. vstupního řádku, zatímco vypadala jako by byl prázdný. Pojďme to tedy prozkoumat:
$ 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! Vidíte ty ^M
známky? Používají se k nahrazení jinak neviditelného znaku návratu vozíku. odkud se to vzalo? No, dikt
Protokol, stejně jako jakýkoli jiný internetový protokol, používá CRLF jako zakončení linky. Stáhli jsme je tedy jako součást našich ukázkových souborů. Další informace o posunu řádku a návratu vozíku naleznete v přehybu
a fmt
článek. Ale prozatím vysvětluje, proč kočka
považuje 6. řádek za neprázdný.
-e
:zobrazení neviditelných znaků, včetně konce řádku
-e
volba funguje jako -v
kromě toho přidá také znak dolaru ($
) před každým znakem pro odřádkování, čímž se explicitně zobrazí konec řádků:
$ 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
:zobrazení neviditelných znaků, včetně tabulátorů
-t
volba funguje jako -v
kromě toho zobrazí také tabulky pomocí ^I
stříška (tabulátor je uložen jako bajt s hodnotou 9 a I
v ASCII je 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
:zobrazit všechny skryté znaky
Jak jsem již krátce zmínil, pokud chcete zobrazit všechny netisknutelné znaky, včetně tabulek a značek na konci řádku, budete muset použít oba -e
a -t
možnosti:
$ 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:Neužitečné použití příkazu cat v Linuxu
Žádný článek o kočce
příkaz by byl kompletní bez zmínky o anti-vzoru „Useless Use of Cat“.
Objeví se, když použijete cat
pouze za účelem odeslání obsahu souboru na standardní vstup jiného příkazu. Toto použití cat
příkazu se říká „neužitečný“, protože prosté přesměrování nebo parametr názvu souboru by to udělalo a udělalo by to lépe. Ale příklad za tisíc slov:
$ 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
[...]
Ve výše uvedeném příkladu jsem použil potrubí k zobrazení obsahu uuoc.txt
soubor s méně
pager:
cat uuoc.txt | less
Takže jediný účel kočky
příkaz měl napájet standardní vstup méně
příkaz s obsahem uuoc.txt
soubor. Stejné chování bych získal pomocí přesměrování shellu:
less < uuoc.txt
Ve skutečnosti, méně
příkaz, stejně jako mnoho příkazů, také přijímá název souboru jako argument. Takže jsem to mohl jednoduše napsat:
less uuoc.txt
Jak vidíte, není potřeba kočka
tady. Pokud zmiňuji anti-vzor „Useless Use of Cat“, je to proto, že pokud jej použijete veřejně na fóru nebo jinde, nepochybně vás na to někdo upozorní argumentem, že vytvoříte „proces navíc pro nic“. “
Musím přiznat, že dlouho jsem byl s takovými komentáři dost odmítavý. Koneckonců, na našem moderním hardwaru by vytvoření jednoho procesu navíc pro jednorázovou operaci nemohlo způsobit tolik režie.
Ale při psaní tohoto článku jsem provedl rychlý experiment a porovnal čas potřebný s UUOC a bez něj pomocí testovacího awk
skript pro zpracování 500 MB dat pocházejících z pomalého média.
K mému překvapení nebyl rozdíl ani zdaleka zanedbatelný:
Důvodem však není vytvoření extra procesu. Ale kvůli zvláštnímu čtení/zápisu a přepínání kontextu dochází k UUOC (jak to můžete odvodit z času stráveného prováděním systémového kódu). Takže skutečně, když pracujete na velkých souborech dat, navíc cat
příkaz má nezanedbatelné náklady. Pokud jde o sebe, budu se nyní snažit být ostražitější! a ty? Pokud máte příklady zbytečného používání kočky, neváhejte se o ně s námi podělit!