首頁 > 軟體

Linux中的cat命令:基本和高階範例

2020-06-16 16:44:02

cat 命令的名稱來源於單詞catenate,此單詞的意思是一個接一個地連線起來。cat 命令的用途是連線檔案或標準輸入並列印,這個命令常用來顯示檔案內容,或者將 幾個檔案連線起來顯示,或者從標準輸入讀取內容並顯示。

# 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

如果要將該串聯的結果儲存在檔案中,則必須使用shell重定向:

cat felidae.txt felis.txt > result.txt
cat result.txt

即使它的主要設計目標是連線檔案,cat實用程式通常也只使用一個引數來將該檔案的內容顯示在螢幕上,就像我在上面範例的最後一行中所做的那樣。

A.使用帶有標準輸入的cat命令

當沒有任何引數使用時,cat命令將從其標準輸入讀取資料並將其寫入其標準輸出 - 這通常是無用的...除非您使用某些選項來轉換資料。 我們稍後會討論幾個有趣的選項。

除了檔案路徑之外,cat命令還將 - 特殊檔名理解為標准輸入的別名。 這樣,您可以在命令列上給出的檔案之間插入從標準輸入讀取的資料:

# Insert a separator between the two concatenated files
echo '----' | cat felis.txt - felidae.txt

B.使用cat命令和二進位制檔案

1.加入拆分檔案

cat命令不對檔案內容做任何假設,因此它將很樂意使用二進位制資料。 重新加入由split或csplit命令破壞的檔案可能有用的東西。 或者像我們現在一樣加入部分下載:

#
# 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

我們現在有兩個一半的影象。 您可以使用ImageMagick的顯示器或gimp或任何其他能夠讀取影象檔案的軟體開啟前半部分並看到它“損壞”:

display first-half
# -or-
gimp first-half
# -or-
firefox first-half

如果你研究我使用的curl命令,你會看到這兩個部分完全互補。 前半部分是從位元組0到50000,後半部分是從位元組50001到檔案末尾。 它們之間不應該缺少資料。 所以我們只需要將兩個部分組合在一起(按正確的順序)以獲取完整的檔案:

cat first-half second-half > image.jpg
display image.jpg

2.使用可流式檔案格式

您不僅可以使用cat命令“重新加入”分成幾個部分的二進位制檔案,但在某些情況下,您還可以通過這種方式建立新檔案。 對於像MPEG傳輸流視訊檔(.TS檔案)檔案格式,這種方法效果特別好:

# 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

我們現在可以使用cat命令組合所有這些傳輸流視訊檔,在輸出中獲得完全有效的TS檔案:

cat fadein.ts still.ts fadeout.ts > video.ts
mplayer video.ts

由於TS檔案格式,您可以按照您想要的順序組合這些檔案,甚至可以在參數列中多次使用相同的檔案在輸出視訊中建立迴圈或重複。顯然,如果我們使用動畫影象,這會更有趣,但我會讓你自己這樣做:許多消費級裝置記錄TS檔案,如果他們不記錄,你仍然可以使用ffmpeg轉換幾乎任何視訊檔到傳輸流檔案。不要猶豫,使用評論部分分享您的作品!

3.破解cpio檔案

作為最後一個範例,讓我們看看如何使用cat命令組合幾個cpio檔案。但這一次,它不會那麼簡單,因為它需要一些關於cpio存檔檔案格式的知識。

cpio存檔按順序儲存檔案的後設資料和內容,這使其適合與cat實用程式進行檔案級連線。不幸的是,cpio存檔還包含一個用於標記存檔結尾的預告片:

# 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

對於cpio二進位制存檔,好的新內容是預告片具有280位元組的固定長度。 因此,使用head standard命令,我們可以輕鬆地將其刪除:

# 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.必需的貓命令選項

在使用各種二進位制檔案格式之後,讓我們通過研究專門為處理這些檔案而客製化的幾個選項來回到普通的舊文字檔案。 雖然不是POSIX標準的一部分,但這些選項可以在BSD和GNU cat實現中移植。 請注意我不會假裝在這裡詳盡無遺,因此請檢查該人以檢視系統中cat支援的完整選項列表!

-n:數位行

使用n選項,cat命令將為每個輸出行新增其行號字首:

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選項編號輸出行。 這意味著從一個輸入檔案切換到下一個輸入檔案時,計數器不會被重置,如果您自己嘗試以下命令,您將看到它:

cat -n feli*.txt

-s:抑制重複的空輸出行

使用-s選項,cat命令將僅折疊多個連續的空行:

 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
linuxidc@linuxidc:~$ 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;

在上面的範例中,您可以看到,在預設輸出中,第10行和第11行是空的。 新增-s選項時,第二個空行被丟棄。

-b:僅編號非空行

與前面兩個選項有些相關,-b選項會對行進行編號,但忽略空行:

$ 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

上面的範例使用cat命令的兩個範例,其中包含管道中的不同選項。內部編號來自第一個cat命令使用的-b選項。外部編號來自第二隻貓使用的-n選項。

如您所見,第一行和最後一行未使用-b選項編號,因為它們是空的。但是第6行怎麼樣?為什麼它仍然使用-b選項進行編號?好吧,因為它是一個空白行 - 但不是空行,我們將在下一節中看到。

-v,-e,-t:顯示非列印字元

三個選項-v,-e`和`-t用於顯示不同的不可見字元集。即使集合重疊,也沒有“全包”選項,因此如果要顯示所有不可見字元,則必須將它們組合在一起。

-v:檢視不可見的字元

-v選項顯示除插入符號和製表符號以外的帶插入符號和元符號的所有非列印字元。

使用該選項,控制字元將顯示為插入符號(^),後跟相應的ASCII字元(例如,回車符,位元組13,顯示為^M,因為ASCII中的M為64 + 13),以及具有高字元的字元 - 階位設定將以“元”符號M-出現,其後是對應於7個低位的表示(例如,位元組141將顯示為M-^M,因為141是128 + 13)。

雖然看似深奧,但在使用二進位制檔案時,該功能可能很有用,例如,如果要檢查嵌入在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^@^@^B@^@^@
^@^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 (

-v選項的另一個用例是查詢可能洩漏到文字檔案中的控制字元。 如果你還記得它,我們上面有一個奇怪的問題,-b選項編號為第6個輸入行,而它看起來像是空的。 所以讓我們調查一下:

$ 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

啊啊! 你看到那些^M標記了嗎? 它們用於替換否則不可見的回車符。 它從哪裡來的? 好吧,與任何其他Internet協定一樣,dict協定使用CRLF作為行終止符。 所以我們將它們作為範例檔案的一部分下載。 您可以在fold和fmt文章中了解有關換行和回車的更多資訊。 但就目前而言,它解釋了為什麼貓認為第6行不是空的。

-e:顯示不可見的字元,包括行尾

-e選項的作用類似於-v選項,除了它還會在每個換行符之前新增一個美元符號($),從而明確顯示行的結尾:

$ 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:顯示不可見的字元,包括索引標籤

-t選項的工作方式與-v選項類似,不同之處在於它還會使用^ I條符號表示法顯示製表符(製表符儲存為儲存值9的位元組,而ASCII格式為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:顯示所有隱藏的字元

正如我已經簡要提到的那樣,如果要顯示所有非列印字元,包括製表符和行尾標記,則需要同時使用-e和-t選項:

$ 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$
$

額外獎勵:在Linux中無用的cat命令

如果沒有提到“無用的Cat”反模式,那麼關於cat命令的文章就不會完整。

當您將cat用於將檔案內容傳送到另一個命令的標準輸入的唯一目的時,就會發生這種情況。 使用cat命令被稱為“無用”,因為簡單的重定向或檔名引數可以完成這項工作,並且可以做得更好。 但是一個值得千言萬語的例子:

$ 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
[...]

在上面的例子中,我使用一個管道來顯示uuoc.txt檔案的內容,並使用較少的分頁器:

cat uuoc.txt | less

因此,cat命令的唯一目的是使用uuoc.txt檔案的內容提供less命令的標準輸入。 我會使用shell重定向獲得相同的行為:

less < uuoc.txt

事實上,較少的命令與許多命令一樣,也接受檔名作為引數。 所以我可以簡單地寫一下:

less uuoc.txt

如你所見,這裡不需要cat。如果我提到“無用的cat”反模式,這是因為,如果你在一個論壇或其他地方公開使用它,毫無疑問有人會指出你的論點,你會建立一個“額外的過程,什麼也沒有。 ”

我必須承認,很長一段時間我對這些評論都很不屑一顧。畢竟,在我們的現代硬體上,為一次性操作產生一個額外的過程不會導致那麼多開銷。

但在撰寫本文時,我做了一個快速實驗,通過測試awk指令碼比較UUOC和非UUOC所需的時間來處理來自慢速媒體的500MB資料。

令我驚訝的是,差異遠非微不足道,使用cat命令將資料傳輸到awk將導致嚴重的效能損失

但是,原因不是要建立額外的進程。但是由於額外的讀/寫和上下文切換,UUOC會產生(因為你可以從執行系統程式碼的時間推斷它)。實際上,當您處理大型資料集時,額外的cat命令具有不可忽視的成本。至於我自己,我現在會盡力保持警惕!你呢?如果你有無用cat的例子,請不要猶豫與我們分享!


IT145.com E-mail:sddin#qq.com