Linux Cat团队。 基本和高级示例

继续我们的Linux命令之旅,今天我们将看一下该命令 cat

姓名 cat 代表 catenate,此命令的主要目的是通过顺序将多个输入文件发送到标准输出来连接多个输入文件:

# Давайте сначала получим некоторые примеры файлов данных:
curl -so - dict://dict.org/'d:andreyex:gcide' | unexpand -a -t 3 |
  sed -Ee '/^151/,/^[.]/!d;/^[.0-9]/s/.*//' > andreyex.txt
curl -so - dict://dict.org/'d:ubuntu:gcide' | unexpand -a -t 3 |
  sed -Ee '/^151/,/^[.]/!d;/^[.0-9]/s/.*//' > ubuntu.txt

# Объединение файлов
cat andreyex.txt ubuntu.txt

如果要将此串联的结果存储在文件中,则需要使用shell重定向:

cat andreyex.txt ubuntu.txt > result.txt
cat result.txt

即使项目的主要目的是合并文件,该实用程序 cat 它也经常只用一个参数在屏幕上显示此文件的内容,就像我们在上面示例的最后一行中所做的那样。

A.在标准输入中使用cat命令

当不带任何参数使用时,命令 cat 将从其标准输入读取数据并将其写入标准输出,这几乎没有用处…除非您使用某些参数来转换数据。 稍后我们将讨论一些有趣的选项。

除了文件路径,该命令 cat 也明白 - 特殊文件名作为标准输入的别名。 因此,您可以在命令行中指定的文件之间插入从标准输入读取的数据:

# Вставить разделитель между двумя соединенными файлами
echo '----' | cat ubuntu.txt - andreyex.txt

B.将猫与二进制文件一起使用

1.合并分割文件

团队 cat 不假设文件的内容,因此它将与二进制数据一起使用。 对于合并使用命令分割的文件可能有用的东西 split 或者 csplit… 或附加到部分下载,就像我们现在要做的那样:

#
# Изображение AndreyEx (CC-SA 3.0)
# Оптимизировать использование полосы пропускания, разбив загрузку на две части
# (в нашей системе мы наблюдаем 10%-ный прирост по сравнению с "полной" загрузкой)
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看到它已“损坏”, displaygimp或任何其他能够读取图像文件的软件:

display first-half
# -или-
gimp first-half
# -или-
firefox first-half

如果研究我们使用的curl命令,您会发现这两个部分完美地互补。 前半部分从0字节到50,000,后半部分从50001字节到文件末尾。 两者之间不应缺少任何数据。 因此,我们只需要将两个部分链接在一起(以正确的顺序)即可获得完整的文件:

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

2.处理流文件格式

您不仅可以使用命令 cat 为了“分解”分成多个部分的二进制文件,在某些情况下,您还可以通过这种方式创建新文件。 这对于“无标题”或“流式”文件格式(例如视频文件(文件) .TS)MPEG传输流:

# Давайте сделаем еще видео файл с нашего изображения
ffmpeg -y -loop 1 -i cat.jpg -t 3  
    -c:v libx264 -vf scale=w=800:h=-1 
    still.ts

# Давайте сделаем fade-in из того же изображения
ffmpeg -y -loop 1 -i cat.jpg -t 3  
    -c:v libx264 -vf scale=w=800:h=-1,fade=in:0:75 
    fadein.ts

# Давайте сделаем затухание из того же изображения
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 还有一个用于标记存档结束的容器:

# Создать два подлинных CPIO` bin ' архива:
$ find ubuntu.txt andreyex.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命令,我们有一种简单的方法可以将其删除:

# Каждый архив заканчивается 280-байтовым контейнером.
# Для catenate оба архива, просто убрать контейнер
# в конце первой части:
$ head -c-280 part1.cpio | cat - part2.cpio > cat.cpio
$ cpio -it < cat.cpio
ubuntu.txt
andreyex.txt
cat.jpg
239 blocks

C. cat命令的基本选项

在研究了不同的二进制文件格式之后,让我们通过检查几个专门用于这些文件的选项来返回普通的旧文本文件。 尽管这些选项不是POSIX标准的一部分,但它们可以跨BSD和GNU版本移植,用于 cat… 请注意:我们不假装我们将在这里处理所有要点,因此请检查页面 man查看系统命令支持的选项的完整列表 cat

-n:数字字符串

有选项 n 团队 cat 通过行号在每个输出行前添加前缀:

cat -n andreyex.txt
     1
     2    andreyex andreyex 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 {andreyex}.
     8            [WordNet 1.5]
     9

在参数中 -n 输出线数。 这意味着从一个输入文件移到另一个输入文件时不会重置计数器,因为您将自己尝试以下命令来查看:

cat -n feli*.txt

-s:禁止重复的空白输出行

有选项 -s 团队 cat 刷新几个连续的空行:

 cat -n ubuntu.txt andreyex.txt | sed -n 8,13p
     8       lynx ({ubuntu lynx}) is also called {Lynx lynx}.
     9       [1913 Webster +PJC]
    10
    11
    12    andreyex andreyex n.
    13       a natural family of lithe-bodied round-headed fissiped
[email protected]:~$ cat -ns ubuntu.txt andreyex.txt | sed -n 8,13p
     8       lynx ({ubuntu lynx}) is also called {Lynx lynx}.
     9       [1913 Webster +PJC]
    10
    11    andreyex andreyex 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 andreyex.txt | cat -n
     1
     2         1    andreyex andreyex 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 {andreyex}.
     8         7              [WordNet 1.5]
     9

上面的示例使用了命令的两个实例 cat 在容器中具有不同的参数。 使用该选项执行内部编号 -b与第一个命令一起使用 cat… 外部编号随选件一起提供 -n与第二个命令一起使用 cat

如您所见,第一行和最后一行没有使用该选项编号 -b因为他们是空的。 但是第六行呢? 为什么仍然用选项编号 -b? 好吧,因为它是一个空格填充的字符串,但不是空的,我们将在下一部分中看到。

-v,,-e-t:显示不可打印的字符

三种选择,-v-e `, and `-t 用于显示各种不可见符号集。 即使集合重叠,也没有包罗万象的选项,因此,如果要显示所有不可见的字符,则必须将它们合并。

-v:查看不可见字符

选项 -v 显示所有不可打印的回车符和元符号,行和制表符除外。

使用此选项,控制字符将显示为脱字符号( ^),然后加上适当的ASCII字元(例如回车,显示13个字元) ^M 作为 M (以ASCII-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^@^@^[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 (

此参数的另一个用例 -v 用于搜索可能泄漏到文本文件中的控制字符。 如果您还记得这一点,则上面的选项会给我们带来一个奇怪的问题,-b表示输入的第六行,当它看起来为空时。 因此,让我们调查以下内容:

$ cat -v andreyex.txt
andreyex andreyex 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 {andreyex}.^M
          [WordNet 1.5]^M

啊啊! 你看到这些迹象了吗 ^M? 它们用于替换后向不可见的回车符。 这个从哪里来? 好协议,dict像任何其他Internet协议一样,它使用CRLF作为行终止符。 因此,我们已将它们下载为示例文件的一部分。 但是现在它解释了为什么 cat 认为第六行不为空。

-e:显示不可见的字符,包括行尾

选项 -e 与选项一起使用 -v,只会添加一个美元符号($)在每个换行符之前,从而清楚地显示该行的结尾:

$ cat -e andreyex.txt
$
andreyex andreyex 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 {andreyex}.^M$
          [WordNet 1.5]^M$
$

-t:显示不可见的字符,包括标签

选项 -t 作为一种选择 -v,除了也会使用光标显示表格数据 ^I (书签存储为保留字节值9,并且 I ASCII中为64 + 9 = 73):

$ cat -t andreyex.txt

andreyex andreyex 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 {andreyex}.^M
^I^I  [WordNet 1.5]^M

-et:显示所有隐藏的字符

如前所述,如果要显示所有不可打印的字符,包括表格和行尾标记,则需要使用这些选项 -e-t

$ cat -et andreyex.txt
$
andreyex andreyex 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 {andreyex}.^M$
^I^I  [WordNet 1.5]^M$
$

奖励:无用的Linux 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 本来是命令的标准输入 less 与文件内容 uuoc.txt… 使用shell重定向,我们将得到相同的行为:

less < uuoc.txt

实际上,团队less像许多命令一样,它也接受文件名作为参数。 所以我们可以这样写:

less uuoc.txt

如您所见,这里不需要使用命令 cat… 我们提到“无用的猫”反模式是因为,如果您在论坛或其他地方公开使用它,无疑会有人指出您创建了“多余的东西”的论点。

我必须承认,很长一段时间以来,我们对这样的评论都是不屑一顾的。 毕竟,在我们的现代硬件上,为一次操作添加一个额外的过程不会导致过多的开销。

但是在撰写本文时,我们进行了一个快速实验,通过测试脚本比较了使用和不使用UUOC所需的时间。 awk 处理来自慢速媒体的500 MB数据。

令我们惊讶的是,两者之间的差异并不大。

但是,原因不是要创建其他过程。 但是由于额外的读/写和上下文切换,UUOC接管了(如何从执行系统代码的时间中推断出它)。 因此,的确,当您使用大型数据集时,额外的命令 cat 具有不利的成本。 对于我们来说,我们将尽力对此保持警惕! 你呢? 如果您有没有用的Cat示例,请随时与我们分享!

Sidebar