Skip to content

第四章 文件内容查看

查看文件内容的常见命令

  • cat
  • more 和 less
  • head 和 tail
  • nl
  • tailf

cat 命令

语法:

shell
用法:cat [选项]... [文件]...

常用选项:
  -n, 对输出的所有行编号
  -b, 对输出的所有行编号(不含空白行)
  -t, 将制表符(tab)显示为^I
  -e, 在每行结束处显示"$"
  -s, 当连续空白行数量大于1时,合并为1个空白行

cat 命令会一次性将文件的完整内容全部显示出来,不适合大文件。

查看文件所有内容

shell
cat HelloWorld.java

查看文件所有内容,并且添加行号

shell
cat -n HelloWorld.java

查看文件所有内容,添加行号,但空白行不加行号

shell
cat -b HelloWorld.java

查看文件所有内容,将制表符显示为^I

shell
cat -t HelloWorld.java

查看文件所有内容,在每行结束处显示"$"

shell
cat -e HelloWorld.java

查看文件所有内容,合并多个连续的空白行为 1 个空白行

shell
cat -s HelloWorld.java

一次查看多个文件

shell
cat a.txt b.txt

使用 cat 合并文件

shell
cat a.txt b.txt > c.txt

加上行号之后输出到另一个文件

shell
cat -n HelloWorld.java > HelloWorld2.java

清空文件内容

shell
cat /dev/null > HelloWorld.java

more 命令

more 命令和 cat 命令的相同点和不同点:

  • 相同点:more 和 cat 在开始读取文件的时候,都是一次性的将文件全部内容装载到缓存中。
  • 不同点:cat 是一次性的全部输出打印。more 可以进行部分打印(一屏一屏的打印)。
shell
用法:
more [选项] <文件>...

常用选项:
  -<number> 每个屏幕的行数 +<number> 从行号开始显示文件
  +/<pattern> 从匹配的位置前两行开始显示内容
  -p 以清除原内容的方式进行翻页。

常用操作:
  回车键 【显示下一行】
  空格键 【显示下一页】
  ctrl + b 【显示上一页】
  = 【显示行号】
  :f 【显示文件名的同时显示行号】
  q 【退出 more 命令】

这里有日志文件:log.txt,内容如下:

shell
2021.10.1 zhangsan
2021.10.2 lisi
2021.10.3 wangwu
2021.10.4 zhaoliu
2021.10.5 admin
2021.10.6 zhangsan
2021.10.7 lisi
2021.10.8 wangwu
2021.10.9 zhaoliu
2021.10.10 qianqi
2021.10.11 zhouyu
2021.10.12 huanggai
2021.10.13 zhugeliang
2021.10.14 simayi
2021.10.15 maimaiti
2021.10.16 erdaye
2021.10.17 sandaye
2021.10.18 zhangsan
2021.10.19 lisi
2021.10.20 wangwu
2021.10.21 zhaoliu
2021.10.22 qianqi
2021.10.23 zhoubapi
2021.10.24 doudizhu
2021.10.25 nongmin
2021.10.26 sunwukong
2021.10.27 zhubajie
2021.10.28 shaseng
2021.10.29 wujing
2021.10.30 baigujing
2021.10.31 java
2021.11.1 oracle
2021.11.2 mysql
2021.11.3 jdbc
2021.11.4 servlet
2021.11.5 jsp
2021.11.6 spring
2021.11.7 mybatis
2021.11.8 springmvc
2021.11.9 web
2021.11.10 html
2021.11.11 css
2021.11.12 java
2021.11.13 sun

案例 1:从第 3 行起,查看文件内容。

shell
more +3 log.txt

案例 2:每屏显示 4 条记录。

shell
more -4 log.txt

案例 3:从文件中查找"java"字符串的行

shell
more +/java log.txt

案例 4:查看进程,每 5 条为一屏,翻屏时清空原内容

shell
ps -ef | more -5 -p

less 命令

less 工具也是对文件或其它输出进行分页显示的工具,应该说是 linux 正统查看文件内容的工具,功能极其强大。less 的用法比起 more 更加的有弹性。使用 less 时,可以使用 [pageup] [pagedown] 等按键的功能来往前往后翻看文件,更容易用来查看一个文件的内容!除此之外,在 less 中可以拥有更多的搜索功能。

less 命令用法

有这样的一个文件:usernames.txt

shell
zhangsan
lisi
wangwu
zhaoliu
sunwukong
zhubajie
wusong
linchong
huanggai
songjiang
ZHANGSAN
lisi
wangwu
zhaoliu
sunwukong
zhubajie
wusong
linchong
huanggai
songjiang
ZHANGSAN
lisi
wangwu
zhaoliu
sunwukong
zhubajie
wusong
linchong
huanggai
songjiang
zhangsan
lisi
wangwu
zhaoliu
sunwukong
zhubajie
wusong
linchong
huanggai
songjiang
zhangsan
lisi
wangwu
zhaoliu
sunwukong
zhubajie
wusong
linchong
huanggai
songjiang
zhangsan
lisi
wangwu
zhaoliu
sunwukong
zhubajie
wusong
linchong
huanggai
songjiang
zhangsan
lisi
wangwu
zhaoliu
sunwukong
zhubajie
wusong
linchong
huanggai
songjiang
zhangsan
lisi
wangwu
zhaoliu
sunwukong
zhubajie
wusong
linchong
huanggai
songjiang
zhangsan
lisi
wangwu
zhaoliu
sunwukong
zhubajie
wusong
linchong
huanggai
songjiang
zhangsan
lisi
wangwu
zhaoliu
sunwukong
zhubajie
wusong
linchong
huanggai
songjiang
zhangsan
lisi
wangwu
zhaoliu
sunwukong
zhubajie
wusong
linchong
huanggai
songjiang
zhangsan
lisi
wangwu
zhaoliu
sunwukong
zhubajie
wusong
linchong
huanggai
songjiang
zhangsan
lisi
wangwu
zhaoliu
sunwukong
zhubajie
wusong
linchong
huanggai
songjiang
zhangsan
lisi
wangwu
zhaoliu
sunwukong
zhubajie
wusong
linchong
huanggai
songjiang
zhangsan
lisi
wangwu
zhaoliu
sunwukong
zhubajie
wusong
linchong
huanggai
songjiang
zhangsan
lisi
wangwu
zhaoliu
sunwukong
zhubajie
wusong
linchong
huanggai
songjiang
zhangsan
lisi
wangwu
zhaoliu
sunwukong
zhubajie
wusong
linchong
huanggai
songjiang
zhangsan
lisi
wangwu
zhaoliu
sunwukong
zhubajie
wusong
linchong
huanggai
songjiang
zhangsan
lisi
wangwu
zhaoliu
sunwukong
zhubajie
wusong
linchong
huanggai
songjiang
zhangsan
lisi
wangwu
zhaoliu
sunwukong
zhubajie
wusong
linchong
huanggai
songjiang
shell
用法:less [选项] 文件

常用选项:
-g 只标志当前搜索到的关键词所在行
-I 忽略搜索时的大小写(注意:是大写 I)
-m 显示类似 more 命令的百分比
-N 显示每行的行号
+num 从第 num 行开始显示

常用操作:
/字符串:向下搜索“字符串”的功能
?字符串:向上搜索“字符串”的功能

n:重复前一个搜索(与 / ? 有关)
N:反向重复前一个搜索(与 / ? 有关)

y 向前滚动一行
回车键 向后滚动一行

u 向前滚动半页
d 向后滚动半页

b 向前翻一页
空格键 向后翻一页

g 移动到第一行
G 移动到最后一行

= 显示详细信息(第几行,共多少行,内容的字节数量等)

v 使用 vim 编辑器进行编辑

q 退出 less 命令

[pagedown] 向下翻动一页
[pageup] 向上翻动一页

less 命令标记兴趣点

在感兴趣的位置添加标记:

  • 先按 m 键 (set mark)
  • 输入标记名称,例如标记名字为:x

需要回到感兴趣的位置时:

  • 先按 ' 键 (goto mark)
  • 输入标记名称 x

less 命令实时监控文件动态变化

第一步:在窗口 1 中执行:less +F log.txt

第二步:在窗口 2 中执行:ps -ef >> log.txt

注意:在监控的过程中,按 ctrl + c 是终止监控,可以继续使用 less 命令的相关操作。按大写 F,再次进入监控模式。

注意:log.txt 是一个文件名。只有机器自动写入或通过输出重定向写入的才可以被监控。

less 命令查看多个文件

less log.txt log2.txt

  • 输入:n 跳转到 log2.txt
  • 输入:p 跳转到 log.txt

less 命令结合管道一起使用

ps -ef | less -N

head 命令

head 命令:显示文件头部内容。

shell
用法:head [选项]... [文件]...
将每个指定文件的前 10 行输出到标准输出。
如果指定了多于一个文件,在每块输出之前附加文件名称作为头部。

参数:
  -c 输出前几个字符
  -n 指定行数
  -q 不显示包含给定文件名的文件头

前三行:

前 9 个字符:

显示多个文件的前 3 行:

不带文件名标识:

tail 命令

tail 命令:显示文件尾部内容。

shell
用法:tail [选项]... [文件]...
显示每个指定文件的最后 10 行并输出至标准输出。
若指定了多于一个文件,程序会在每段输出的开始添加相应文件名作为头。

参数:
  -c 输出最后几个字符
  -f 随文件增长即时输出新增数据
  -n 指定行数
  -q 不输出文件名的头

默认显示文件末尾的后 10 行:

指定行数:

一次查看多个文件:

不显示文件名:

监控文件变化:

在窗口 1 中:

在窗口 2 中:

可以看到窗口 1 发生了变化:

nl 命令

nl 命令是比较专业的显示行号的命令。

用法如下:

  • nl -b a 所有行添加行号,包括空白行;
  • nl -b t 给行添加行号,不包括空白行(默认行为,和直接使用 nl 一样效果);
  • nl -n ln 行号在自己栏位左侧显示;
  • nl -n rn 行号在自己栏位的右侧显示 ;
  • nl -n rz 显示行号,行号栏位不满时,自动补 0 ;
  • nl -w 行号栏位的占用的位数。

文件内容如下:

java
public class HelloWorld{
        public static void main(String[] args){
                System.out.println("Hello World");
        }
}

class UserService{
        public void logout(){
                System.out.println("system log out!");
        }
}

执行以下命令:

shell
nl HelloWorld.java

执行结果:

执行以下命令:显示所有行的行号,包括空白行。

shell
nl -b a HelloWorld.java

执行结果:

执行以下命令:显示行号,不包括空白行。(这是一种默认的方式,和“nl HelloWorld.java”效果一样

shell
nl -b t HelloWorld.java

执行以下命令:行号在行号栏位左侧显示

shell
nl -n ln HelloWorld.java

执行结果:

执行以下命令:行号在行号栏位右侧显示

shell
nl -n rn HelloWorld.java

执行结果:

执行以下命令:行号栏位自动补 0

shell
nl -n rz HelloWorld.java

执行结果:

执行以下命令:设置栏位的字符数量

shell
nl -n rz -w 3 HelloWorld.java

执行结果:

tailf 命令

与 tail -f 不同的是,如果文件不增长,它不会去访问磁盘文件。tailf 特别适合那些便携机上跟踪日志文件,因为它能省电,因为减少了磁盘访问。tailf 命令不是个脚本,而是一个用 C 代码编译后的二进制执行文件,某些 Linux 安装之后没有这个命令。

CentOS 系统是不支持该命令的,可以按照以下步骤添加这个命令:

第一步:cd 命令切换到/usr/local 目录下,新建 tailf.c 文件,该文件内容如下:

c
/* tailf.c -- tail a log file and then follow it
 * Created: Tue Jan 9 15:49:21 1996 by faith@acm.org
 * Copyright 1996, 2003 Rickard E. Faith (faith@acm.org)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * less -F and tail -f cause a disk access every five seconds. This
 * program avoids this problem by waiting for the file size to change.
 * Hence, the file is not accessed, and the access time does not need to be
 * flushed back to disk. This is sort of a "stealth" tail.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <malloc.h>
#include <sys/stat.h>
//#include "nls.h"
#define _(s) s

static size_t filesize(const char \*filename)
{
    struct stat sb;

    if (!stat(filename, &sb)) return sb.st_size;
    return 0;

}

static void tailf(const char *filename, int lines)
{
    char **buffer;
    int head = 0;
    int tail = 0;
    FILE *str;
    int i;

    if (!(str = fopen(filename, "r"))) {
    fprintf(stderr, _("Cannot open \"%s\" for read\n"), filename);
    perror("");
    exit(1);
    }

    buffer = malloc(lines * sizeof(*buffer));
    for (i = 0; i < lines; i++) buffer[i] = malloc(BUFSIZ + 1);

    while (fgets(buffer[tail], BUFSIZ, str)) {
    if (++tail >= lines) {
        tail = 0;
        head = 1;
    }
    }

    if (head) {
    for (i = tail; i < lines; i++) fputs(buffer[i], stdout);
    for (i = 0; i < tail; i++)     fputs(buffer[i], stdout);
    } else {
    for (i = head; i < tail; i++)  fputs(buffer[i], stdout);
    }
    fflush(stdout);

    for (i = 0; i < lines; i++) free(buffer[i]);
    free(buffer);

}

int main(int argc, char **argv)
{
    char       buffer[BUFSIZ];
    size_t     osize, nsize;
    FILE       *str;
    const char *filename;
    int        count;

    //setlocale(LC_ALL, "");
    //bindtextdomain(PACKAGE, LOCALEDIR);
    //textdomain(PACKAGE);

    if (argc != 2) {
    fprintf(stderr, _("Usage: tailf logfile\n"));
    exit(1);
    }

    filename = argv[1];

    tailf(filename, 10);

    for (osize = filesize(filename);;) {
    nsize = filesize(filename);
    if (nsize != osize) {
        if (!(str = fopen(filename, "r"))) {
        fprintf(stderr, _("Cannot open \"%s\" for read\n"), filename);
        perror(argv[0]);
        exit(1);
        }
        if (!fseek(str, osize, SEEK_SET))
                while ((count = fread(buffer, 1, sizeof(buffer), str)) > 0)
                    fwrite(buffer, 1, count, stdout);
        fflush(stdout);
        fclose(str);
        osize = nsize;
    }
    usleep(250000);     /* 250mS */
    }
    return 0;
}

第二步:首先确保当前目录在/usr/local 下,如果不在该目录下,请使用 cd 命令切换到/usr/local。然后编译 c 语言程序:

shell
[root@localhost local]# gcc -o /usr/bin/tailf tailf.c

出现以上提示信息表示当前系统中没有 gcc 编译器,需要安装,输入 y 表示同意安装,再有提示,则继续输入 y 即可。

第三步:测试 tailf 命令是否可用,直接输入 tailf 会出现以下提示,表示 tailf 命令可以使用了。

tailf 命令和“tail -f”一个效果,都是用来实时监控文件变动的。只不过 tailf 是专业的只负责监控日志文件变化的一个命令。我们来测试一下。

日志文件内容如下:

Plain
日志信息第 1 行
日志信息第 2 行
日志信息第 3 行
日志信息第 4 行
日志信息第 5 行
日志信息第 6 行
日志信息第 7 行
日志信息第 8 行
日志信息第 10 行
日志信息第 11 行
日志信息第 12 行
日志信息第 13 行
日志信息第 14 行
日志信息第 15 行
日志信息第 16 行
日志信息第 17 行
日志信息第 18 行
日志信息第 19 行
日志信息第 20 行

执行以下命令:

shell
tailf localhost.log

执行结果:

可以再开启一个新的命令窗口,然后向日志文件中追加内容,如下:

这时可以看到 tailf 命令窗口如下: