# 文件内容查阅

查阅一个文件内容是,这里有相当多有趣的指令来了解下, 最常使用的可以说是 cat 、more、less,那么当查阅一个很大型的文件的时候, 想要在几百兆的文件内容中找到我们想要的数据怎么办?下面的指令能发挥出一些作用

  • cat:由第一行开始显示文件内容
  • tac:从最后一行开始显示,可以看出 tac 是 cat 的倒着写
  • nl:显示的时候顺道输出行号
  • more:一页一页的显示文件内容
  • less:与 more 类似,但是比 more 更好的是,他可以往前翻页
  • head 只看头几行

# 直接检视文件内容

直接查阅一个文件的内容可以使用 cat、tac、nl 这几个指令

# cat(concatenate)

cat [-AbEnTv]
1
  • A:相当于 -vET 的整合选项,可列出一些特殊字符而不是空白
  • b:列出行号,仅针对非空白行做行号显示,空白行不标行号
  • E:将结尾的断行字符 $ 显示出来
  • n:打印出行号(包含空白行)
  • T:将 tab 按键以 ^I 显示出来
  • v:列出一些看不出来的特殊字符

实践练习

[root@study tmp]# cat /etc/issue
\S
Kernel \r on an \m

# 带行号显示,最后还有一行空白行呢。对于大文件要找某个特定的行时,有点用处
[root@study tmp]# cat -n /etc/issue
     1  \S
     2  Kernel \r on an \m
     3  
1
2
3
4
5
6
7
8
9

下面练习显示特殊的内容

[root@study tmp]# cat -A /etc/man_db.conf
#^I^I*MANPATH*     ->^I*CATPATH*$
#$
MANDB_MAP^I/usr/man^I^I/var/cache/man/fsstnd$
MANDB_MAP^I/usr/share/man^I^I/var/cache/man$

# 上面只是部分内容,说下差异
# 断行以 $ 显示,可以发现每行后面都有 $ ,这个其实就 window 中的换行把?
# tab 以 ^I 显示
# windows 的断行字符是 ^M$
# 这部分在 vim 软件介绍时会再次说明
1
2
3
4
5
6
7
8
9
10
11

# tac 反向列示

# 从最后一行开始显示
[root@study tmp]# tac /etc/issue

Kernel \r on an \m
\S

1
2
3
4
5
6

# nl 添加行号打印

nl [-bnw] 文件
1
  • b:指定行号指定的方式,主要有两种

    • -b a:表示不论是否为空行,也同样列出行号(类似 cat -n)
    • -b t:如果有空行,空行不要列出行号(默认值)
  • n:列出行号表示的方法,主要有三种

    • -b ln:行号在屏幕的最左方显示
    • -b rn:行号在自己字段的最右方显示,且不加 0
    • -b rz:行号在自己字段的最有方显示,且加 0
  • w:行号字段的占用字符数

实践练习

# 用 nl 列出 /etc/issue 的内容
# 默认不显示空行的行号
[root@study tmp]# nl /etc/issue
     1  \S
     2  Kernel \r on an \m

# 显示空行行号
[root@study tmp]# nl -b a /etc/issue
     1  \S
     2  Kernel \r on an \m
     3  
# 行号自动补 0,前面说的左右,看下面的对比,这个右是指,行号区域的左右
[root@study tmp]# nl -b a -n rz /etc/issue
000001  \S
000002  Kernel \r on an \m
000003  
[root@study tmp]# nl -b a -n rn /etc/issue
     1  \S
     2  Kernel \r on an \m
     3  
[root@study tmp]# nl -b a -n ln /etc/issue
1       \S
2       Kernel \r on an \m
3       

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 可翻页检视

# more 一页一页翻动

[root@study tmp]# more /etc/man_db.conf
#
#
# This file is used by the man-db package to configure the man and cat paths.
# It is also used to provide a manpath for those without one by examining
# their PATH environment variable. For details see the manpath(5) man page.
#
--More--(14%)   # 重点在这一行,你的光标也会在这里等待你的指令
1
2
3
4
5
6
7
8

在 more 程序中,有几个按键可以按:

  • 空格键(space):向下翻一页
  • Enter:向下翻一行
  • /字符串:在显示的内容中,向下搜索「字符串」这个关键词
  • q:立即离开 more
  • b 或 ctrl+b:向前翻页,只针对文件有用,对管线(管道 |)无用

实践练习

more /etc/man_db.conf
...
--More--(14%)   # 光标在这里,一定要在英文输入状态下直接按 / 才会进入到搜索模式,让你输入文字
/MANPATH   # 这里搜索 MANPATH 这个字符串,查找下一个直接按 n 就可以了
1
2
3
4

# less 一页一页翻动

# 使用指令后,就会进入到 less 环境
less /etc/man_db.conf

# This file is used by the man-db package to configure the man and cat paths.
# It is also used to provide a manpath for those without one by examining

注意,刚进入的时候,没有光标,可以直接输入 : 或则方向下键,就会在最下面出现 「:光标」这里就可以输入指令了
1
2
3
4
5
6
7

可以使用的按键和指令有

  • 空格键:向下翻一页
  • pagedown:向下翻一页
  • pageup:向上翻一页
  • /字符串:向下搜索字符串;注意这个斜杠也是需要输入的,不是在 「:」输入,:也和这个是一个功能
  • ?字符串:向上搜索字符串
  • n:重复前一个搜索(与 / 或 ?有关)
  • N:反向的重复前一个搜索
  • g:前进到这个资料的第一行
  • G:前进到这个资料的最后一行去(注意是大写)
  • q:离开 less 这个程序

此外,man page 就是调用 less 来显示说明文件内容的,所以看上去很相似

笔者工作中查看日志中有用得数据的时候,就是这个 less 了,但是只知道 shift+g 可以前进到最后一行去,原来 shift+g 其实就是输入了大写的 G 指令

# 资料摘取

可以将输出的资料做一个最简单的摘取,如去除文件前面几行(head)或则后面几行(tail), 需要注意的是, head 和 tail 都是以行为单位来进行摘取的

# head 去除前面几行

head [-n number] 文件

-n:后面接数字,表示摘取几行
1
2
3
# 默认显示前 10 行,可以指定显示 20 行
head -n 20 /etc/man_db.conf

# 注意后面的数值为负数
# 该文件共有 131 行,这里是的意思就是,从尾部 -128 行,剩下的内容显示
# 也就是说,忽略显示后 128 行的数据
[root@study tmp]# head -n -128 /etc/man_db.conf
#
#
# This file is used by the man-db package to configure the man and cat paths.

1
2
3
4
5
6
7
8
9
10
11

# tail 取出后面几行

tail [-nf number] 文件

-n :后面接数字,表示显示几行
-f :表示持续侦测后面所接的档名,要等到按下 ctrl+c 才会结束 tail 的侦测
1
2
3
4
# 默认显示最后 10 行
tail /etc/man_db.conf
# 显示最后 20 行
tail -n 20 /etc/man_db.conf
# 忽略显示前 100 行的数据,也就是说显示 100 行后的数据
tail -n +100 /etc/man_db.conf


# 这个就是笔者最常用查看某个项目当前滚动日志的方式了
tail -f /var/log/messages
1
2
3
4
5
6
7
8
9
10

组合使用示例

# 获取 第 11 到 20 行的数据
# 思路是:先取前 20 行数据出来,再从这 20 行里面取后 10 行数据
[root@study tmp]# head -n 20 /etc/man_db.conf | tail -n 10

# 这个 | 就是管线的意思
1
2
3
4
5

|:管线/管道符,前面的指令所输出的信息,请透过管线交由后续的指令继续使用。后续会详细讲解

上面的例子,其实我也不知道到底取出来的行数对不对,那么就可以使用管线来组合其他的指令使用

# 先使用 cat -n 显示行号,再交给后续的指令
# 我这里是显示 第 18 行到 20 行的内容
[root@study tmp]# cat -n /etc/man_db.conf | head -n 20 | tail -n 3
    18  #MANDATORY_MANPATH                      /usr/src/pvm3/man
    19  #
    20  MANDATORY_MANPATH                       /usr/man

1
2
3
4
5
6
7

# 非纯文本 od

上面讲解了读取出文本的内容,那么想阅读非文本文件呢?比如查看 /usr/bin/passwd 文档, 使用上面提出来的指令读取就会乱码。

可以使用 od 指令来读取

od [-t TYPE] 文件
1

type 选项为:

  • a:利用默认的字符来输出
  • c:使用 ASCII 字符来输出
  • d[size]:十进制(decimal)输出数据,每个整数占用 size bytes
  • f[size]:浮点数(floating)输出数据
  • o[size]:八进制(octal)
  • x[size]:十六进制(hexadecimal)

实践练习

使用 ASCII 展示

[root@study ~]# od -t c /usr/bin/passwd
0000000 177   E   L   F 002 001 001  \0  \0  \0  \0  \0  \0  \0  \0  \0
0000020 003  \0   >  \0 001  \0  \0  \0   H   2  \0  \0  \0  \0  \0  \0
0000040   @  \0  \0  \0  \0  \0  \0  \0 220   e  \0  \0  \0  \0  \0  \0
0000060  \0  \0  \0  \0   @  \0   8  \0  \t  \0   @  \0 035  \0 034  \0
0000100 006  \0  \0  \0 005  \0  \0  \0   @  \0  \0  \0  \0  \0  \0  \0

# 最左边第一栏以 8 进制来表示 bytes 数。
# 比如 00000020 表示是第16 个 bytes (2x8)
1
2
3
4
5
6
7
8
9

使用 8 进制位列出存储值与 ASCII 的对照表

[root@study ~]# od -t oCc /etc/issue
0000000 134 123 012 113 145 162 156 145 154 040 134 162 040 157 156 040
          \   S  \n   K   e   r   n   e   l       \   r       o   n    
0000020 141 156 040 134 155 012 012
          a   n       \   m  \n  \
0000027

# 上面是八进制表示,下面是对应的 ascii 字符
1
2
3
4
5
6
7
8

对照指令对于工程师来说可能更有用处,上面是文件是一个纯文本文件,显示了字符的 ACCIS 对照表, 百度了下, ACCIS 可以与上面的各种进制来对照

比如 password 字符串,需要他的 10 进制对照表

# 可以使用管道符来给 od 处理
[root@study ~]# echo password | od -t dCc
0000000  112   97  115  115  119  111  114  100   10
           p    a    s    s    w    o    r    d   \n
0000011
1
2
3
4
5

# 修改文件时间或新建文件 touch

使用 ls 指令的时候,提到过每个文件 linux 底下都会记录许多的时间参数,其实是有三个主要的变动时间:

  • modification time(mtime)

    当文档 内容数据 变更时。该时间会被更新。

  • status time(ctime)

    当文件 状态 改变时。比如权限与数学被更改了

  • access time(atime)

    当文件 内容被取用 时。比如我们使用 cat 去读取 /etc/man_db.conf ,该时间就会改变

[root@study ~]# date;ls -l /etc/man_db.conf ;ls -l --time=atime /etc/man_db.conf ;ls -l --time=ctime /etc/man_db.conf
20191013日 星期日 21:33:52 CST
-rw-r--r--. 1 root root 5171 1031 2018 /etc/man_db.conf # 2018/10/31 建立的 mtime
-rw-r--r--. 1 root root 5171 1013 15:36 /etc/man_db.conf # 10月13号 读取过 atime
-rw-r--r--. 1 root root 5171 104 18:22 /etc/man_db.conf # 10月4号 更新过状态 ctime

# 笔者就现在使用了 cat /etc/man_db.conf,也没有发现时间变更,不知道是啥原因
1
2
3
4
5
6
7

当你看到一个未来时间的文件,这个是有可能的,因为支持多时区,安装系统行为不当,就有可能导致这种情况发生

可以使用 touch 来修订时间

touch [-acdmt] 文件
1
  • a:仅修订 access time
  • c:仅修改文件的时间,若该文件不存在则不建立新文件
  • d:后面可以接欲修订的日期而不用目前的日期,也可以使用 --date="日期或时间"
  • m:仅修改 mtime
  • t:后面可以接欲修订的时间而不用目前的时间,格式为 YYYYMMDDhhmm

实践练习

[mrcode@study ~]$ cd /tmp/
[mrcode@study tmp]$ touch testtouch
[mrcode@study tmp]$ ls -l testtouch
-rw-rw-r--. 1 mrcode mrcode 0 Oct 13 21:45 testtouch

# 注意到这个文件的大小是 0,在预设的状态下,如果 touch 没有接文件
# 则该文件的三个时间(atime、ctime、mtime 都会更新为目前的时间。
# 若该文件不存在,则会主动建立一个新的空文件


# 复制一个文件,假设复制全部的属性,并检查日期
[mrcode@study tmp]$ cp -a ~/.bashrc bashrc
[mrcode@study tmp]$ date; ll bashrc ; ll --time=atime bashrc ; ll --time=ctime bashrc
Sun Oct 13 21:48:24 CST 2019
-rw-r--r--. 1 mrcode mrcode 231 Aug  8 20:06 bashrc # mtime
-rw-r--r--. 1 mrcode mrcode 231 Oct 13 14:38 bashrc # atime
-rw-r--r--. 1 mrcode mrcode 231 Oct 13 21:47 bashrc # ctime
# 属性完全被复制,mtime 与源文件相同,该文件是刚刚建立的, ctime 就是当前时间

# 可以将日期调整为两天前
[mrcode@study tmp]$ touch -d "2 days ago" bashrc
[mrcode@study tmp]$ date; ll bashrc ; ll --time=atime bashrc ; ll --time=ctime bashrc
Sun Oct 13 21:51:31 CST 2019
-rw-r--r--. 1 mrcode mrcode 231 Oct 11 21:51 bashrc # mtime
-rw-r--r--. 1 mrcode mrcode 231 Oct 11 21:51 bashrc # atime
-rw-r--r--. 1 mrcode mrcode 231 Oct 13 21:51 bashrc # ctime
# 可以看到前两个实际变化了,ctime 又变成当前时间了

# 将日期调整为诶指定的时间 2014/06/15 00:00
[mrcode@study tmp]$ touch -t 201406150000 bashrc
[mrcode@study tmp]$ date; ll bashrc ; ll --time=atime bashrc ; ll --time=ctime bashrc
Sun Oct 13 21:54:31 CST 2019
# 由于时间太久远,默认的格式显示不全的,没有显示时分格式
-rw-r--r--. 1 mrcode mrcode 231 Jun 15  2014 bashrc
-rw-r--r--. 1 mrcode mrcode 231 Jun 15  2014 bashrc
-rw-r--r--. 1 mrcode mrcode 231 Oct 13 21:54 bashrc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

那么 touc 中最常用的功能是:

  • 建立一个空的文件
  • 将某个文件日期秀固定为目前(mtime 与 atime)
  • 比较重要的是 mtime,关心这个文件内容是什么时候被更新的