Linux学习(6)--文件内容查阅

时间:2022-12-24 14:55:31

如果我们要查阅一个文件的内容时,该怎么办呢?这里有很多有趣的命令可以来分享一下:最常用的显示文件内容的命令可以说是 cat 与 more 及 less了。此外,如果我们要查看一个几百MB的文件,但是只需要最后的几行字,该怎么办呢?用tail啊!此外,tac也可以!那我们先来看看各个命令的用途:

  • cat:从第一行开始显示文件内容
  • tac:从最后一行开始显示,可以发现tac就是cat倒着写!
  • nl:显示的时候,顺便输出行号
  • more:一页一页的显示文件内容
  • less:与more类似,更好的是,他可以往前翻页
  • head:只看头几行
  • tail:只看尾巴上的几行
  • od:以二进制的方式读取文件内容

1.直接查看文件内容

直接查看一个文件的内容可以使用 cat/tac/nl 这几个命令

- cat(concatenate)

[root@VM_174_157_centos mvtest2]# cat [-AbEnTv]
选项与参数:
-A:相当于-vET的整合,可列出一些特殊字符而不是空白而已
-b:列出行号,仅针对非空白行做行号显示,空白行不标行号
-E:将结尾的断行字符$显示出来
-n:打印出行号,连同空白行也会显示,与-b相对
-T:将[tab]按键以^I显示出来
-v:列出一些看不出来的特殊字符


范例1:查看/etc/issue这个文件的内容
[root@VM_174_157_centos ~]# cat /etc/issue
\S <==我这里是改过的,正常情况下应该是类似这样CentOS release 5.3 (Final)
Kernel \r on an \m

范例2:承上题,如果还要加上行号呢?
[root@VM_174_157_centos ~]# cat -n /etc/issue
1 \S
2 Kernel \r on an \m
3
#如果不想要空白行显示,可以用-b试试哦

范例3:将/etc/xinetd.conf的内容完整的像是出来,包含特殊字符
[root@VM_174_157_centos ~]# cat -A /etc/xinetd.conf
#$
....(中间省略)....
$ defaults$
{$
# The next two items are intended to be a quick access place to$
....(中间省略)....
^Ilog_type^I= SYSLOG daemon info $
^Ilog_on_failure^I= HOST$
^Ilog_on_success^I= PID HOST DURATION EXIT$
....(中间省略)....
includedir /etc/xinetd.d$
$
#我们可以看到使用[tab]和空格差不多,都是一堆空白,所以我们无法知道两者的差别
#此时使用cat -A就能够发现了,Windows的断行字符是^M$

当然如果文件内容的行数超过40行以上,我们还是配合后面的 more 或者 less来执行比较好!

- tac(反向)

[root@VM_174_157_centos ~]# tac /etc/issue

Kernel \r on an \m
\S
#这个就不需要多说了,和前面一做对比就知道了

- nl(添加行号显示)

[root@VM_174_157_centos ~]# nl [-bnw] 文件
选项与参数:
-b:指定行号指定的方式,只要有两种
-b a:表示不论是否为空行,也同样列出行号(cat -n)
-b t:如果有空行,空的那一行不要列出行号(默认值)
-n:列出行号表示的方法,主要有三种
-n ln:行号在屏幕的最左方显示
-n rn:行号在自己字段的最右方显示,且不加0
-n rz:行号在自己字段的最右方显示,且加0
-w:行号字段的占用行数


范例1:用nl列出/etc/issue的内容
[root@VM_174_157_centos ~]# nl /etc/issue
1 \S
2 Kernel \r on an \m

#第三行为空白行,如果要加上行号呢

[root@VM_174_157_centos ~]# nl -b a /etc/issue
1 \S
2 Kernel \r on an \m
3
#如果要让行号前面自动补0呢?

[root@VM_174_157_centos ~]# nl -b a -n rz /etc/issue
000001 \S
000002 Kernel \r on an \m
000003
#预设的是6位,如果我想要改成3位呢?

[root@VM_174_157_centos ~]# nl -b a -n rz -w 3 /etc/issue
001 \S
002 Kernel \r on an \m
003
#这就变成3位了

2.可翻页查看

- more(一页页翻动)

[root@VM_174_157_centos etc]# 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--(28%) <==重点在这里,你的光标也会在这里等待你的命令

如果more后面接的文件内容行数大于屏幕输出的行数时,就会出现类似上面的图式。我们还可以在more运行过程中,有以下指令:

  • 空格(space):向下翻一页
  • Enter :向下翻一行
  • /字符串 :代表在这个显示的内容中,向下查询【字符串】这个关键字
  • :f :立刻显示出文件名以及目前显示的行数
  • q :代表立刻离开more,不再继续显示
  • b或者Ctrl-b :代表往回翻页,不过只对文件有用,对管道无用

- less(一页页翻动)

[root@VM_174_157_centos etc]# 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
# their PATH environment variable. For details see the manpath(5) man page.
...(中间省略)...
: <==这里可以等待你输入命令

less的用法比more更有弹性,因为more的时候,没办法往前翻,但是less就可以用[pageup][pagedown]等按键的功能来往前往后翻看文件。

除此之外,less里面有更多的搜寻功能,不止可以往下搜寻,也可以往上搜寻。可以输入的指令有:

  • 空格键(space):向下翻一页
  • [pageup] : 向上翻一页
  • [pagedown] :向下翻一页
  • /字符串 :向下查询【字符串】
  • ?字符串 :向上查询【字符串】
  • n :重复前一个查询
  • N :反向的重复前一个查询
  • q :离开less

3.数据选取

我们可以将输出的数据做一个最简单的选取,那就是取出前面(head)与取出后面(tail)文字的功能。不过,要注意的是,head与tail都是以行为单位来进行数据选取的。

- head(取出前面几行)

[root@VM_174_157_centos etc]# head [-n number] 文件
选项与参数:
-n:后面接数字,代表显示几行的意思


[root@VM_174_157_centos etc]# head /etc/man_db.conf
#默认的情况中,显示前面10行,如果要显示20行,则这么写:
[root@VM_174_157_centos etc]# head -n 20 /etc/man_db.conf

范例1:如果后面100行的数据都不打印,只打印/etc/man_db.conf的前面几行,该怎么办
[root@VM_174_157_centos etc]# head -n -100 /etc/man_db.conf

如果接的是负数,比如有140行,就不打印后100行,只打印前40行

- tail(取出后面几行)

[root@VM_174_157_centos etc]# tail [-n number] 文件
选项与参数:
-n:后面接数字,代表显示几行的意思
-f:表示持续检测后面所接的文件名,要等到按下Ctrl-C才会结束tail的检测


[root@VM_174_157_centos etc]# tail /etc/man_db.conf
#默认的情况中,显示后面10行,如果要显示20行,则这么写:
[root@VM_174_157_centos etc]# tail -n 20 /etc/man_db.conf

范例1:如果不知道/etc/man_db.conf有几行,却只想列出100行以后的数据?
[root@VM_174_157_centos etc]# tail -n +100 /etc/man_db.conf

范例2:持续检测/var/log/messages的内容
[root@VM_174_157_centos etc]# tail -f /var/log/messages
<==要等到Ctrl-C的命令才会离开tail的检测

在范例2中,由于/var/log/message随时会有数据写入,你想要让该档案有数据写入时就立刻显示到屏幕上,就利用-f。新加入的数据都会被显示到屏幕上,直到你按下Ctrl-C才会离开tail的检测。

tips:如果我想要显示/etc/man_db.conf的第11到20行呢?

这个不难想,我取前20行,再取后10行。所以结果就是head -n 20 /etc/man_db.conf | tail -n 10,这样就可以得到第11行到20行了。但是里面涉及到管线操作,我们要在后面才会讲到。

4.非纯文本文件:od

我们上面提到的都是在查阅纯文本文件的内容。那么万一我们想要查阅非文本文件,例如/usr/bin/password这个执行文件的内容时,又怎么办呢?事实上,由于执行文件通常是二进制文件(binary file),以正常的读取会乱码,所以这个时候我们就需要用到od了。

[root@VM_174_157_centos etc]# od [-t TYPE] 文件
选型或者参数:
-t:后面可以接各种“类型(TYPE)”的输出,例如
a:利用默认的字符来输出
c:使用ASCII字符来输出
d[size]:利用十进制(decimal)来输出数据,每个整数占用size bytes
f[size]:利用浮点数(floating)来输出数据,每个整数占用size bytes
o[size]:利用八进制(octal)来输出数据,每个整数占用size bytes
x[size]:利用十六进制(hexadecimal)来输出数据,每个整数占用size bytes


范例1:请将/usr/bin/passwd的内容使用ASCII方式来显示
[root@VM_174_157_centos ~]# od -t c /usr/bin/passwd
...(前面省略)...
0064360 \0 \0 \0 \0 \0 \0 \0 \0 212 \0 \0 \0 001 \0 \0 \0
0064400 006 \0 \0 \0 \0 \0 \0 \0 304 H \0 \0 \0 \0 \0 \0
0064420 304 H \0 \0 \0 \0 \0 \0 \t \0 \0 \0 \0 \0 \0 \0
0064440 \0 \0 \0 \0 \0 \0 \0 \0 004 \0 \0 \0 \0 \0 \0 \0
0064460 \0 \0 \0 \0 \0 \0 \0 \0 220 \0 \0 \0 001 \0 \0 \0
0064500 002 \0 \0 \0 \0 \0 \0 \0 320 H \0 \0 \0 \0 \0 \0
0064520 320 H \0 \0 \0 \0 \0 \0 003 \v \0 \0 \0 \0 \0 \0
0064540 \0 \0 \0 \0 \0 \0 \0 \0 \b \0 \0 \0 \0 \0 \0 \0
0064560 \0 \0 \0 \0 \0 \0 \0 \0 230 \0 \0 \0 001 \0 \0 \0
0064600 002 \0 \0 \0 \0 \0 \0 \0 324 S \0 \0 \0 \0 \0 \0
...(后面省略)...
#最左边第一栏是以8进位来表示bytes数,以上面范例来说,0000020代表
#开头是第16个bytes(2x8)的内容之意

范例2:请将/etc/issue这个文件的内容以8进位列出储存值与ASCII的对照表
[root@VM_174_157_centos ~]# 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 \n
0000027
#如上所示,可以发现每个字符可以对应到的数值
#例如 e 对应的记录数值为145,转成十进制:1x8^2+4x8+5=101

5.修改文件时间或建立新文件:touch

我们在介绍 ls 的时候,提到在linxu下记录有很多的时间参数,其实是有三个主要的变动时间,那么三个时间的意义是什么?

  • modification time(mtime)

    当该文件的内部数据变更时,就会更新这个时间!内部数据指的是文件的内容,而不是文件的属性或者权限

  • status time(ctime)

    当该文件的状态(status)改变时,就会更新这个时间。比如属性或者权限更改了,就会更新这个时间

  • access time(atime)

    当该文件的内容被取用时,就会更新这个读取时间(acess)。我们用cat去读取/etc/man_db.conf,就会更新该文件的atime了

比如我们来看看自己的 /etc/man_db.conf 这个文件的时间

[root@VM_174_157_centos ~]# ls -l /etc/man_db.conf 
-rw-r--r--. 1 root root 5171 Jun 10 2014 /etc/man_db.conf

在默认的情况下,ls 显示出来的是该文件的mtime,也就是这个文件的内容上次被改动的时间。

文件的时间是很重要的,因为,如果文件的时间误判的话,可能会造成程序无法顺利运行。那么如果我发现一个来自未来时间的文件,该怎么办呢?这个时候就要用到touch这个命令了。

tips:不要怀疑系统时间会来自未来,很多时候都有可能有这个问题。举例来说在安装过后系统时间可能会被改变。在某些比GMT(Greenwich Mean Time)早的时区,如果安装的时候没有注意,那么文件就有可能来自于几小时后。

[root@VM_174_157_centos ~]# touch [-acdmt] 文件
选项与参数:
-a:仅修改access time
-c:仅修改文件的时间,若该文件不存在则不建立新文件
-d:后面可以接想修改的日期而不用目前的日期,也可以使用--date=“日期或时间”
-m:仅修改mtime
-t:后面可以接想修改的时间而不用目前的时间,格式为[YYMMDDhhmm]



范例1:新建一个空的文件并查看时间
[root@VM_174_157_centos ~]# cd /tmp
[root@VM_174_157_centos tmp]# touch testtouch
[root@VM_174_157_centos tmp]# ls -l testtouch
-rw-r--r-- 1 root root 0 Feb 20 09:43 testtouch
#注意到,这个文件的大小是0,在默认的情况下,如果touch后面有接文件,
#则该文件的三个时间(atime/ctime/mtime)都会更新为当前的时间,若该文件
#不存在,则会主动创建一个新的文件!

范例2:将~/.bashrc复制成为bashrc,假设复制所有的属性,查看其日期
[root@VM_174_157_centos tmp]# cp -a ~/.bashrc bashrc
[root@VM_174_157_centos tmp]# ll bashrc; ll --time=atime bashrc; ll --time=ctime bashrc
-rw-r--r--. 1 root root 176 Dec 29 2013 bashrc <==这是mtime
-rw-r--r--. 1 root root 176 Dec 29 2013 bashrc <==这是atime
-rw-r--r--. 1 root root 176 Feb 20 09:47 bashrc <==这是ctime

这里的ll就是ls -l的意思,是一个被“做出来”的命令别名。分号“;”是代表连续命令的下达!执行结果我们可以看到,由于这个文件是刚刚被复制过来的,因此状态(ctime)与读取时间就是现在的时间。如果我们想改变这个文件的时间,我们可以这么做:

范例3:修改范例2的bashrc文件,并将日期调整为两天前
[root@VM_174_157_centos tmp]# touch -d "2 days ago" bashrc
[root@VM_174_157_centos tmp]# ll bashrc; ll --time=atime bashrc; ll --time=ctime bashrc
-rw-r--r--. 1 root root 176 Feb 18 10:12 bashrc
-rw-r--r--. 1 root root 176 Feb 18 10:12 bashrc
-rw-r--r--. 1 root root 176 Feb 20 10:12 bashrc
#跟上个范例比较看看,本来是12月29日,变成了2月18日

范例4:将上个范例的bashrc日期改为2007/09/15 2:02
[root@VM_174_157_centos tmp]# touch -t 0709150202 bashrc
[root@VM_174_157_centos tmp]# ll bashrc; ll --time=atime bashrc; ll --time=ctime bashrc
-rw-r--r--. 1 root root 176 Sep 15 2007 bashrc
-rw-r--r--. 1 root root 176 Sep 15 2007 bashrc
-rw-r--r--. 1 root root 176 Feb 20 10:38 bashrc
#注意看看,日期在atime与mtime都改变了,但是ctime则是记录目前的时间

通过touch这个命令,我们可以轻易的修改文件的日期和时间。并且也可以建立一个空的文件。不过要注意的是,我们复制一个文件的时候,复制所有的属性但也没办法复制ctime这个属性。无论如何,比较重要的还是mtime,我们关心的常常是这个文件的内容是什么时候被更改的。

touch命令最常被使用的情况是:

  • 建立一个空的文件
  • 将某个文件日期修改为目前(mtime与atime)