LINUX中的head和tail命令
1. 概述
在 Linux 中,从输入文件中获取部分文本是一种常见的操作。
有两个基本且广泛使用的命令行实用程序可以从输入中输出部分文本:head 命令和tail 命令。
在本教程中,我们将通过示例讨论这两个命令的典型用法。
2. head和tail命令介绍
head和tail命令都是GNU coreutils 包的成员。默认情况下,它们安装在所有 Linux 发行版中。
正如它们的名字所暗示的, head命令将输出文件的第一部分,而tail命令将打印文件的最后部分。**两个命令都将结果写入标准输出。
在后面的部分中,我们将仔细研究每个命令,并通过示例学习如何使用它们。
3. head命令
head命令的语法非常简单:
head [OPTIONS] FILES
让我们准备一个文件(numbers_en.txt)作为输入示例,以更好地理解命令:
$ cat numbers_en.txt
one : 1
two : 2
three : 3
four : 4
...
ninety-seven : 97
ninety-eight : 98
ninety-nine : 99
one hundred : 100
该文件包含从 1 到 100 的数字的英文单词。因此,该文件有 100 行。
默认情况下, head命令会将输入文件的前十行写入标准输出:
$ head numbers_en.txt
one : 1
two : 2
three : 3
four : 4
five : 5
six : 6
seven : 7
eight : 8
nine : 9
ten : 10
3.1. 输出特定行数
使用 -n选项,我们可以让 head命令输出前n行而不是默认的 10。
例如,如果我们想将前七行打印到标准输出,我们将使用 -n 7:
$ head -n 7 numbers_en.txt
one : 1
two : 2
three : 3
four : 4
five : 5
six : 6
seven : 7
如果我们将-n选项与–后面的数字一起传递,例如-n -x,则head命令将打印文件的最后x行以外的所有行。**
例如,如果我们想忽略文件中的最后 97 行,我们会执行*-n -97*:
$ head -n -97 numbers_en.txt
one : 1
two : 2
three : 3
3.2. 输出特定字节数
除了逐行显示文本之外,如果我们传递-c*选项,head命令还可以按字节打印文件内容。*
-c 选项的用法与 -n选项相同,只是按字节而不是按行显示文本。
让我们看一个仅显示文件中第一个单词“one”(3 个字节)的示例:
$ head -c 3 numbers_en.txt
one
3.3. 输出多个文件
head命令还可以处理多个文件。要看到这一点,我们首先准备另一个输入文件numbers_de.txt。该文件与numbers_en.txt非常相似。唯一的区别是文件中的单词是德语而不是英语:
$ cat numbers_de.txt
eins : 1
zwei : 2
drei : 3
vier : 4
...
siebenundneunzig : 97
achtundneunzig : 98
neunundneunzig : 99
(ein)hundert : 100
现在让我们一次性输出两个文件的前五行:
$ head -n 5 numbers_en.txt numbers_de.txt
==> numbers_en.txt <==
one : 1
two : 2
three : 3
four : 4
five : 5
==> numbers_de.txt <==
eins : 1
zwei : 2
drei : 3
vier : 4
fünf : 5
4. tail命令
使用 tail命令的语法也很简单:
tail [OPTIONS] FILES
** tail命令默认将输入文件的最后十行写入标准输出:**
$ tail numbers_en.txt
ninety-one : 91
ninety-two : 92
ninety-three : 93
ninety-four : 94
ninety-five : 95
ninety-six : 96
ninety-seven : 97
ninety-eight : 98
ninety-nine : 99
one hundred : 100
4.1. 输出特定行数
使用 -n选项,我们可以让 tail命令输出最后n行,而不是默认的 10。
此示例显示如何从输入文件中获取最后七行:
$ tail -n 7 numbers_en.txt
ninety-four : 94
ninety-five : 95
ninety-six : 96
ninety-seven : 97
ninety-eight : 98
ninety-nine : 99
one hundred : 100
如果我们将-n选项与“+”后面的数字一起传递,例如“ -n +x ”,tail 命令将从第x*行开始打印,直到文件末尾。*
让我们从第 95 行打印到numbers_en.txt文件的末尾:
$ tail -n +95 numbers_en.txt
ninety-five : 95
ninety-six : 96
ninety-seven : 97
ninety-eight : 98
ninety-nine : 99
one hundred : 100
4.2. 输出特定字节数
与 head命令类似,如果我们将 -cx 选项传递给 tail 命令,它将仅输出输入文件的最后x个字节。
让我们从输入文件中获取最后一个数字100 :
$ tail -c 4 numbers_en.txt
100
在上面的示例中,我们将 4 而不是 3 传递给 -c选项。这是因为最后一行有一个结束换行符,而这个换行符占用了 1 个字节。
4.3. 输出多个文件
与head命令一样,tail命令也可以从多个输入文件中输出。
让我们看一个从两个输入文件打印最后五行的示例:
$ tail -n 5 numbers_en.txt numbers_de.txt
==> numbers_en.txt <==
ninety-six : 96
ninety-seven : 97
ninety-eight : 98
ninety-nine : 99
one hundred : 100
==> numbers_de.txt <==
sechsundneunzig : 96
siebenundneunzig : 97
achtundneunzig : 98
neunundneunzig : 99
(ein)hundert : 100
4.4. 观察文件的变化
有时我们要检查的输入文件正在改变。例如,正在运行的应用程序可能会将其输出附加到日志文件中。
如果我们在更改文件上执行带有*-f选项的tail*命令 ,所有新添加的行都将附加到标准输出。
接下来,让我们看一下这个功能的演示。
首先,我们将创建一个简单的 shell 脚本append_ts.sh。每秒钟将当前时间戳附加到日志文件 ( /tmp/timestamp.log)中,它将附加到日志文件十次:
$ cat ./append_ts.sh
#!/bin/bash
for times in {1..10}
do
echo $(date) >> /tmp/timestamp.log
times=$(($times+1))
sleep 1
done
现在,让我们开始通过tail命令查看日志文件 ,然后我们执行上面的脚本并观察新附加的时间戳是否出现在 tail的输出中:
正如我们所料,所有新添加的行都被打印出来了。
要退出tail命令,我们可以按Ctrl-C。
5. head和tail一起使用
我们已经知道 head命令可以给我们文件的第一部分,而 tail命令可以输出输入文件的最后部分。但是,如果我们想在文件中间获取某些部分怎么办?
为了解决这个问题,我们可以结合这两个简单的命令。
假设我们想从输入文件中获取第 51 到第 55 行:
$ tail -n +51 numbers_en.txt | head -n 5
fifty-one : 51
fifty-two : 52
fifty-three : 53
fifty-four : 54
fifty-five : 55
我们还可以通过以不同的方式组合head命令和tail命令来获得相同的输出:
$ head -n 55 numbers_en.txt | tail -n 5