当前位置: 代码迷 >> 综合 >> Linux笔记 Day10---(split、mv、cut、sort、uniq、wc、head、tail、find、which、whereis、locate命令)
  详细解决方案

Linux笔记 Day10---(split、mv、cut、sort、uniq、wc、head、tail、find、which、whereis、locate命令)

热度:33   发布时间:2024-01-31 07:20:30.0

文章目录

  • 一、split命令
  • 二、mv命令
  • 三、cut命令
  • 四、sort命令
  • 五、uniq命令
  • 六、wc命令
  • 七、head 命令
  • 八、tail命令
  • 九、正则表达式
  • 十、find命令
  • 十一、which命令
  • 十二、whereis命令
  • 十三、locate命令

一、split命令

分割文档的命令 split
split命令用于将一个文件分割成数个。该指令将大文件分割成较小的文件,在默认情况下将按照每1000行切割成一个小文件,同时默认分割后的文件的名称会以 x 作为前缀,以 aa、ab、ac 这样的双字母格式作为后缀,形成 xaa、xab 这样的名称格式。当然也可以给分割后文件指定名字,不过系统还会给指定的名字后添加字母后缀

用法: split [option] [file [prefix]]

选项:

  • -行数 : 指定每多少行切成一个小文件
  • -l 行数: 等价于- 行数
  • -b 字节 : 指定每多少字节切成一个小文件,也可以指定 K、M、G、T 等单位
  • -C字节 : 与参数"-b"相似,但是在切 割时将尽量维持每行的完整性
  • -d:切分后文件名为数字形式
  • -a 后缀长度:默认的后缀长度是 2,也就是按 aa、ab、ac 这样的格式依次编号

【例 1】指定行数切割

将文件"readme"每6行切割成一个文件

[root@admin ~]# split -6 readme 
[root@admin ~]# ls
anaconda-ks.cfg  readme  xab  xad  xaf  xah
dir              xaa     xac  xae  xag  xai
#等价于
[root@admin ~]# split -l 6 readme 

split会将原来的文件"readme"切割成多个以"x"开头的小文件。而在这些小文件中,每个文件都只有6行内容

也可以给分割后的小文件指定名字,不过系统会给你指定的名字后加上字母

[root@admin ~]# split -l 2 readme newreadme
[root@admin ~]# ls
anaconda-ks.cfg  newreadmeab  newreadmeaf  readme
dir              newreadmeac  newreadmeag
file             newreadmead  newreadmeah
newreadmeaa      newreadmeae  newreadmeai

【例 2】指定文件大小来切割

将文件"file"每20M切割成一个文件

[root@admin ~]# ll -h file
-rw-r--r--. 1 root root 100M 7月  21 16:26 file
[root@admin ~]# split -b 20M file
[root@admin ~]# ls
anaconda-ks.cfg  dir  file  readme  xaa  xab  xac  xad  xae

【例 3】
将file文件每20M切割成一个文件同时指定分割后的文件名后缀是数字且长度是4

[root@admin ~]# split -b 50M -a 4 -d file
[root@admin ~]# ls
anaconda-ks.cfg  dir  file  readme  x0000  x0001

二、mv命令

文件/目录改名或变更存储位置的命令 mv

mv 命令(move 的缩写),既可以在不同的目录之间移动文件或目录,也可以对文件和目录进行重命名

用法: mv [选项] 源文件 目标文件

选项:

  • -t:先指定目标,再指定源文件
  • -f:强制覆盖,如果目标文件已经存在,则不询问,直接强制覆盖;
  • -i:交互移动,如果目标文件已经存在,则询问用户是否覆盖(默认选项);
  • -n:如果目标文件已经存在,则不会覆盖移动,而且不询问用户;
  • -v:显示文件或目录的移动过程;
  • -u:若目标文件已经存在,但两者相比,源文件更新,则会对目标文件进行升级

【例 1】移动文件或目录

[dxk@admin ~]$  mv file /tmp   #等价于mv -t /tmp file
#移动之后,源文件会被删除,类似剪切
[dxk@admin ~]$  mkdir dir
[dxk@admin ~]$  mv dir/ /tmp
#也可以移动目录,和 rm、cp 不同的是,mv 移动目录不需要加入 -r 选项

如果移动的目标位置已经存在同名的文件,则同样会提示是否覆盖,因为 mv 命令默认执行的也是 “mv -i” 的别名

[dxk@admin ~]$ touch test
[dxk@admin ~]$ mv test /tmp
mv:县否覆盖"tmp/test"?y
#由于 /tmp 目录下已经存在 test 文件,所以会提示是否覆盖,需要手工输入 y 覆盖移动

【例 2】强制移动

之前说过,如果目标目录下已经存在同名文件,则会提示是否覆盖,需要手工确认。这时如果移动的同名文件较多,则需要一个一个文件进行确认,很不方便

如果我们确认需要覆盖已经存在的同名文件,则可以使用 “-f” 选项进行强制移动,这就不再需要用户手工确认了

[dxk@admin ~]$ touch test
[dxk@admin ~]$ mv -f test /tmp
#就算 /tmp/ 目录下已经存在同名的文件,由于"-f"选项的作用,所以会强制覆盖

【例 3】不覆盖移动

既然可以强制覆盖移动,那也有可能需要不覆盖的移动。如果需要移动几百个同名文件,但是不想覆盖,这时就需要 “-n” 选项(跳过同名的文件)

[root@admin tmp]# touch file1 file2 #在/tmp下有file1、file2文件
[root@admin tmp]# cd 
[root@admin ~]# touch file1 file2 file3 #在家目录下下有file1、file2、file3文件
[root@admin ~]# mv -n -v file1 file2 file3 /tmp #将在家目录下下有file1、file2、file3文件移动到/tmp下
"file3" -> "/tmp/file3"    #-v 选项用于显示移动过程,可以看到只有file3移动过去了
[root@admin ~]# ls
anaconda-ks.cfg  file1  file2    #file1、file2还在家目录下,所以-n选项在有同名的文件则会不移动
[root@admin ~]# 

【例 4】改名

如果源文件和目标文件在同一目录中,那就是改名

[root@admin ~]# ls
anaconda-ks.cfg  file1  file2
[root@admin ~]# mv file1 file
[root@admin ~]# ls
anaconda-ks.cfg  file  file2

目录也可以按照同样的方法改名

【例 5】显示移动过程

如果我们想要知道在移动过程中到底有哪些文件进行了移动,则可以使用 “-v” 选项来查看详细的移动信息

[root@admin ~]# mv -v file1 file2 file3 /tmp/dir
"file1" -> "/tmp/dir/file1"
"file2" -> "/tmp/dir/file2"
"file3" -> "/tmp/dir/file3"

三、cut命令

cut命令用于剪切文件中的数据

cut 是以每一行为一个处理对象

用法: cut OPTION… [FILE]…

选项:

  • -b :以字节为单位进行分割。这些字节位置将忽略多字节字符边界,除非也指定了-n 标志
  • -c :以字符为单位进行分割。
  • -d :自定义分隔符,默认为制表符
  • -f :与-d一起使用,指定显示哪个区域

cut 的定位依据:

所谓“定位依据”,通俗地讲就是,该如何告诉 cut 想定位到哪一段内容进行剪切

cut 命令共接受三类定位方法:

第一,按字节(bytes)定位,用-b选项。
第二,按字符(characters)定位,用-c选项。
第三,按(fields)定位,用-f选项。

【例 1】
在“字节”定位中,如果我想提取每一行的第 1、第 2、第3和第4个字节

-b选项支持形如“1-4”这样的写法,而且多个定位数字之间还可以用逗号隔开

[root@admin ~]# date
2020年 07月 21日 星期二 17:15:30 CST
[root@admin ~]# date | cut -b 1-4 
2020
[root@admin ~]# date | cut -b 1,2,3,4 
2020
[root@admin ~]# date | cut -b 1-4,9,10,15,16
20200721

有一点要注意,cut 命令如果使用了-b选项,那么在执行此命令时,cut 会先把 -b 后面所有的定位数字按照从小到大的顺序排序,然后再依次提取。所以你可以随意颠倒定位数字的顺序

[root@admin ~]# cat demo
hello mysql
hello linux
hello world
[root@admin ~]# cut -b 7-11 demo
mysql
linux
world
[root@admin ~]# cut -b 11,8,7,10,9 demo
mysql
linux
world
#即使我们把定位数字的顺序颠倒着写,所提取出的内容仍然没有变

【例 2】

-b -Num表示从头到第Num个字节,比如:#-3就表示从头到第3个字节
-b Num-表示从第Num个字节到结尾,比如:#3-就表示从第3个字节到结尾

cut 对于区间采用的都是“闭区间”

[root@admin ~]# cut -b -5 demo
hello
hello
hello
[root@admin ~]# cut -b 7- demo
mysql
linux
world
[root@admin ~]# cut -b -4,4- demo #虽然是闭区间但如果有重复的定位只会剪切一个
hello mysql
hello linux
hello world

【例 3】字符定位

[root@admin ~]# cut -c -5 demo
hello
hello
hello
[root@admin ~]# cut -b -5 demo
hello
hello
hello

不过,看着和 -b 没有什么区别?其实不然,看似相同,只是因为该文件中都是单字节字符,所以用 -b 和 -c 没有区别,

[root@admin ~]# file demo 
demo: ASCII text

我们可以看到demo文件是ASCII编码的普通文本文件,这种格式中1个字母就是1个字符也等价于一个字节

如果我们在文档中写入中文,区别就看出来了

[root@admin ~]# vim demo 
[root@admin ~]# cat demo
hello unix
你好 linux
[root@admin ~]# file demo
demo: UTF-8 Unicode text

此时,在文档中添加了中文,该文件的编码格式也发生了变化,UTF-8统一字符编码格式的文本文件,1 个 utf8 数字占 1 个字节、1 个 utf8 英文字母占 1 个字节、1个utf8汉字每个占用 3 个字节或4 个字节

[root@admin ~]# cut -b 2 demo
e
?      #用字节定位,乱码了
[root@admin ~]# cut -c 2 demo
e
好   #字符定位,输出正常

用 -c 则会以字符为单位来提取内容;而 -b 只会以字节(8 位二进制位)来计算,输出的就是乱码了

【例 3】

当遇到多字节字符时,可以使用-n选项,-n选项用于告诉 cut 命令不要将多字节字符拆开,而是合并在一起显示

[root@admin ~]# cut -b 2 demo
e
?      #乱码
[root@admin ~]# cut -nb 2 demo
e
好

【例 4】按域定位

-b 和 -c 只能在固定格式的文档中提取信息,而对于非固定格式就不方便,那么可以按域定位

/etc/passwd 文件,并不像date、w、who 命令的输出信息那样具有固定的格式,而是比较零散的样子。但是,文件中有很多冒号,这些冒号恰当地隔开了每一个有含义的项。这里“有含义的项”,我们就可以认为是“域”

[root@admin ~]# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
……省略部分输出信息……

-d :自定义以什么为分隔符,默认为制表符
-f :与-d一起使用,指定显示哪个区域

[root@admin ~]# cut -d : -f 1,2,3 /etc/passwd
root:x:0      #将文件中的每一行以冒号为分隔符,分为很多列(域),剪切第1,2,3列内容
bin:x:1
daemon:x:2
adm:x:3
lp:x:4
sync:x:5
shutdown:x:6
……省略部分输出信息……

四、sort命令

sort命令用于将文本文件内容加以排序

sort可针对文本文件的内容,以行为单位来排序

**用法:**sort [选项]… [文件]…

常用选项:

  • -b 忽略每行前面开始出的空格字符。
  • -d 排序时,处理英文字母、数字及空格字符外,忽略其他的字符。
  • -f 排序时,将小写字母视为大写字母,亦即忽略大小写。
  • -i 排序时,除了040至176之间的ASCII字符外,忽略其他的字符。
  • -M 将前面3个字母依照月份的缩写进行排序。
  • -n 依照数值的大小排序。
  • -u 意味着是唯一的(unique),输出的结果是去完重了的
  • -o<输出文件> 将排序后的结果存入指定的文件。
  • -r 以相反的顺序来排序。
  • -t<分隔字符> 指定排序时所用的栏位分隔字符。
  • -k Num :以第Num列排序

【例 1】

sort 命令将以默认的方式将文本文件的第一列以ASCII 码的次序排列,并将结果输出到标准输出

[root@admin ~]# cat demo
56fewferg
addsvffgh
18723asld
bdf24435h
333333333
333333333
[root@admin ~]# sort demo
18723asld
333333333
333333333
56fewferg
addsvffgh
bdf24435h

【例 2】

-u:在输出行中排序并去除重复行

[root@admin ~]# cat demo
56fewferg
addsvffgh
18723asld
bdf24435h
333333333
333333333
[root@admin ~]# sort -u demo
18723asld
333333333
56fewferg
addsvffgh
bdf24435h

【例 3】

-r:逆序排序
说明:sort默认的排序方式是升序的,如果想改成降序,就需要加-r选项

[root@admin ~]# sort demo
18723asld
333333333
333333333
56fewferg
addsvffgh
bdf24435h
[root@admin ~]# sort -r demo
bdf24435h
addsvffgh
56fewferg
333333333
333333333
18723asld

【例 4】

-o:将排序结果写入文件中

说明:将排序后的结果写入其他文件中,可以使用–o选项,等价于用重定向将结果写入文件,形如sort filename > newfile。但是若是将排序后的结果输出到原文件中,使用重定向就不行,只能使用-o选项

[root@admin ~]# cat demo
ddsvffgh
18723asld
bdf24435h
333333333
333333333
[root@admin ~]# sort -r demo -o demo
[root@admin ~]# cat demo
ddsvffgh
bdf24435h
333333333
333333333
18723asld

【例 5】

-n:按数值排序
说明:如果按默认方式(字符)排序,当10与2比较时,排序程序会先比较1和2,这样就会出现10放在2前面的情况。所以,最好指明排序的方式

[root@admin ~]# cat demo
14.c++
2.java
13.python
41.c#
35.php
[root@admin ~]# sort demo
13.python
14.c++
2.java
35.php
41.c#
[root@admin ~]# sort -n demo
2.java
13.python
14.c++
35.php
41.c#

【例 6】

sort的-t选项和-k选项:
1)命令格式:sort -t 分隔符 -k 指定列数
(类似于cut命令的-d和-f选项的联合使用)

[root@admin ~]# cat file
apple:10:78
melon:3:24
plum:5:45
pomelo:20:33
lime:14:11
[root@admin ~]# sort -nt : -k 2 file #将file文件中的内容以冒号(:)为分隔符并以第二列进行排序显示结果
melon:3:24
plum:5:45
apple:10:78
lime:14:11
pomelo:20:33

【例 7】
忽略大小写

[root@admin ~]# cat file2
hello
what
Hello
What
echo
Echo
[root@admin ~]# sort file2
echo
Echo
hello
Hello
what
What
[root@admin ~]# sort -f file2
Echo
echo
Hello
hello
What
what

【例 8】

将file文件中的内容以冒号分割,并按第一列的第二个字母进行降序排序

[root@admin ~]# cat file
apple:10:78
melon:3:24
plum:5:45
pomelo:20:33
lime:14:11
[root@admin ~]# sort -t : -rk 1.2 file
apple:10:78
pomelo:20:33
plum:5:45
lime:14:11
melon:3:24

将file文件中的内容以冒号分割,只针对第一个域(即第一列)的第二个字母进行排序

[root@admin ~]# cat file
apple:10:78
melon:3:24
plum:5:45
pomelo:20:33
lime:14:11
longan:17:44
[root@admin ~]# sort -t : -k 1.2 file
melon:3:24
lime:14:11
plum:5:45
pomelo:20:33  #第二个字母都是o所以继续向下一个字母比较,m的ASCII嘛小于n,所以pomelo排在longan之前 
longan:17:44
apple:10:78
[root@admin ~]# sort -t : -k 1.2,1.2 file
melon:3:24
lime:14:11
plum:5:45
longan:17:44   #比较两次的排序结果就不同了
pomelo:20:33
apple:10:78

这里是想说明 -k1.2 和-k 1.2,1.2的含义和不同:
-k 1.2 表示对第一个域(即第一列)的第二个字符开始到本域的最后一个字符为止的字符串进行排序
-k 1.2,1.2 表示只对第一个域(即第一列)的第二个字符进行排序

【例 9】

将file文件中的内容以冒号分割,只针对第一个域(即第一列)的第二个字母进行排序,如果相同则按照第二列的数字进行降序排序

[root@admin ~]# cat file
apple:10:78
melon:3:24
plum:5:45
pomelo:20:33
lime:14:11
longan:17:44
[root@admin ~]# sort -t : -k 1.2,1.2 -k 2,2 -nr file
pomelo:20:33
longan:17:44
lime:14:11
apple:10:78
plum:5:45
melon:3:24

-k 2,2表示只对本域进行排序,如果省略了后面的2,那么就会从第二个域开始到最后一个域位置的内容进行排序

五、uniq命令

去重(只去除相邻的行的重复,所以一般和sort连用)

对指定的ASCII文件或标准输入进行唯一性检查,以判断文本文件中重复出现的行,常用于分析日志;查看tcp各个状态连接数,ip或域名连接数排名等等场景,一般与 sort 命令结合使用

用法: uniq [选项]… [文件1] [文件2]

uniq从已经排好序的文本文件file1中删除重复的行,输出到标准输出或file2,常作为过滤器,配合管道试压(这里指的删除只是在输出内容中对于重复的行只输出一个,源文件中的内容并未改变)
在使用uniq命令前,必须确保操作的文本文件已经sort排序了,因为uniq命令只对相邻行进行去重

常用选项:

  • sort [file] | uniq 等价于 sort -u [file]
[root@admin ~]# sort test
11111111
11111111
23456678
3e4r5t6y
aaaassss
aaaassss
asdfghjk
[root@admin ~]# sort test | uniq
11111111
23456678
3e4r5t6y
aaaassss
asdfghjk
[root@admin ~]# sort -u test
11111111
23456678
3e4r5t6y
aaaassss
asdfghjk
  • -c 在输出行前面加上每行在文件中出现的次数
[root@admin ~]# cat test
11111111
3e4r5t6y
11111111
23456678
aaaassss
asdfghjk
aaaassss
[root@admin ~]# sort test|uniq -c 2 111111111 234566781 3e4r5t6y2 aaaassss1 asdfghjk
  • -d 只显示去重后的行
[root@admin ~]# sort test
11111111
11111111
23456678
3e4r5t6y
aaaassss
aaaassss
asdfghjk
[root@admin ~]# sort test | uniq -d
11111111
aaaassss
  • -f 去重前比较时跳过前N列
[root@admin ~]# sort test
12 22 33 44
13 22 33 44
14 22 33 66
45 33 55 66
55 33 55 66
99 22 33 33
[root@admin ~]# sort test | uniq -f1 #将每一行第一列的数据跳过,然后对每一行进行比较并去重
12 22 33 44 
14 22 33 66
45 33 55 66
99 22 33 33
  • -i 去重前比较时忽略大小写
[root@admin ~]# cat test 
11111111
3e4r5t6y
11111111
23456678
aaaassss
asdfghjk
Aaaassss
[root@admin ~]# sort test | uniq
11111111
23456678
3e4r5t6y
aaaassss
Aaaassss
asdfghjk
[root@admin ~]# sort test | uniq -i
11111111
23456678
3e4r5t6y
aaaassss
asdfghjk
  • -s 去重前比较时跳过前N个字符
[root@admin ~]# sort test
12 22 33 44
13 22 33 44
14 22 33 66
45 33 55 66
55 33 55 66
99 22 33 33
[root@admin ~]# sort test | uniq -s2 #将每一行第前两个字符跳过,然后对每一行进行比较并去重
12 22 33 44
14 22 33 66
45 33 55 66
99 22 33 33
  • -u 去掉所有重复行,只显示唯一行
[root@admin ~]# cat test
11 22 33 44
22 22 33 44 
11 34 66 78
33 22 33 44
11 22 33 44
[root@admin ~]# sort test |uniq
11 22 33 44
11 34 66 78
22 22 33 44 
33 22 33 44
[root@admin ~]# sort test | uniq -u
11 34 66 78
22 22 33 44 
33 22 33 44
  • -w Num:重前比较前Num個字符之后的不做比較
[root@admin ~]# sort test | uniq
11 22 33 44
11 34 66 78
22 22 33 44 
33 22 33 44
[root@admin ~]# sort test | uniq -w 2
11 22 33 44
22 22 33 44 
33 22 33 44
  • -D显示所有重复的行
[root@admin ~]# cat test
11 22 33 44
22 22 33 44 
11 34 66 78
33 22 33 44
11 22 33 44
[root@admin ~]# sort test |uniq
11 22 33 44
11 34 66 78
22 22 33 44 
33 22 33 44
[root@admin ~]# sort test | uniq -D
11 22 33 44
11 22 33 44

六、wc命令

wc(Word Count)命令的功能为统计指定文件中的字节数、字数、行数,并将统计结果显示输出

语法: wc [OPTION]… [FILE]…

常用选项

  • -c 统计字节数。
[root@admin ~]# file file1
file1: UTF-8 Unicode text
[root@admin ~]# cat -ET file1
Hello World !$
你好^I世界$
[root@admin ~]# wc -c file1
28 file1      #此UTF-8编码:一个英文字母占1个字节,1个控制符占1个字节,1个数字占1个字节,1个汉字占3个字节(此处的空格符,制表符,换行符各算一个字节)
  • -l 统计行数
[root@admin ~]# cat file1
Hello World !
你好	世界
[root@admin ~]# wc -l file1
2 file1    #一个英文字母是1个字符,1个控制符是1个字符,1个数字是1个字符,1个汉字是1个字符(此处的空格符,制表符,换行符各算一个字符)
  • -m 统计字符数。这个标志不能与 -c 标志一起使用
[root@admin ~]# cat -ET file1
Hello World !$
你好^I世界$
[root@admin ~]# wc -m file1
20 file1   #
  • -w 统计字数。一个字被定义为由空白、跳格或换行字符分隔的字符串
[root@admin ~]# cat -ET file1
Hello World !$
你好^I世界$
[root@admin ~]# wc -w file1
5 file1
  • -L 打印最长行的长度
[root@admin ~]# cat file2
hello hello hello
hello
[root@admin ~]# wc -L file2
17 file2  #只统计每行的内容,结尾换行符不算在内

七、head 命令

head 命令可以显示指定文件前若干行的文件内容

用法: head [选项] 文件名

常用选项:

  • -n K:这里的 K 表示行数,该选项用来显示文件前 K 行的内容,等价于 -K
    -n -K:使用 “-K” 作为参数,则表示除了文件最后 K 行外,显示剩余的全部内容。
[root@admin ~]# cat file1
Hello World !
你好	世界
hello unix !
hello linux
[root@admin ~]# head -n 1 file1
Hello World !
[root@admin ~]# head -n -1 file1
Hello World !
你好	世界
hello unix !

显示file文件前20行的内容

[root@admin ~]# head -n 20 file
#等价于
[root@admin ~]# head -20 file
  • -c K:这里的 K 表示字节数,该选项用来显示文件前 K 个字节的内容
    -c -K:使用 "-K"作为参数,则表示除了文件最后 K 字节的内容,显示剩余全部内容
[root@admin ~]# cat file1
Hello World !
你好	世界
hello unix !
hello linux
[root@admin ~]# head -c 13 file1
Hello World 
[root@admin ~]# head -c -13 file1
Hello World !
你好	世界
  • -v 显示文件名;注意,如不设置显示的具体行数,则默认显示 10 行的文本数据。
[root@admin ~]# head -v file1
==> file1 <==
Hello World !
你好	世界
hello unix !
hello linux

八、tail命令

tail 命令和 head 命令正好相反,它用来查看文件末尾的数据

用法: tail [选项] 文件名

常用选项:

  • -n K 这里的 K 指的是行数,该选项表示输出最后 K 行,等价于-K
[root@admin ~]# cat file1
Hello World !
你好	世界
hello unix !
hello linux
[root@admin ~]# tail -n 2 file1
hello unix !
hello linux
#等价于
[root@admin ~]# tail -2 file1
hello unix !
hello linux
  • -n +K:表示从文件的第 K 行开始输出
[root@admin ~]# cat file1
Hello World !
你好	世界
hello unix !
hello linux
[root@admin ~]# tail -n +2 file1
你好	世界
hello unix !
hello linux
  • -c K 这里的 K 指的是字节数,该选项表示输出文件最后 K 个字节的内容
[root@admin ~]# cat file1
Hello World !
你好	世界
hello unix !
hello linux
[root@admin ~]# tail -c 12 file1
hello linux     #不要忘记换行符
  • -c +K:表示从文件第 K 个字节开始输出
[root@admin ~]# cat file1
Hello World !
你好	世界
hello unix !
hello linux
[root@admin ~]# tail -c +15 file1
你好	世界
hello unix !
hello linux
  • -f 输出文件变化后新增加的数据
    监听文件的新増内容。tail 命令可以使用 “-f” 选项来实时监听文件的新増内容
[root@admin ~]# tail -f anaconda-ks.cfg %addon com_redhat_kdump --enable --reserve-mb='auto'%end%anaconda
pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty
pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok
pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty
%end
#光标不会退出文件,而会一直监听在文件的结尾处

这条命令会显示文件的最后 10 行内容,而且光标不会退出命令,每隔一秒会检查一下文件是否增加新的内容,如果增加就追加到原来的输出结果后面并显示

常用于监听日志文件

[root@admin ~]# tail -f /etc/log/messages

如果想终止输出,按【Ctrl+c】键中断 tail 命令即可

九、正则表达式

维基百科:
正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本。
百度百科:
正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”))操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式是一种文本模式,该模式描述在搜索文本时要匹配的一个或多个字符串

其实就是由一类特殊字符及文本字符所编写的模式,其中有些字符不表示其字面意义,而是用于表示控制或通配的功能;
分为两类:

  • 基本正则表达式:BRE basic
  • 扩展正则表达式:ERE extend

awk、sed、grep(egrep) 三剑客要想更高效地工作,那一定离不开正则表达式的配合,linux里的正则表达式,主要是基于三剑客的正则表达式

下面我们就透过grep来了解正则表达式:

grep: Global search REgular expression and Print out the line.
作用:文本搜索工具,根据用户指定的“模式(过滤条件)”对目标文本逐行进行匹配检查;打印匹配到的行;
模式:由正则表达式的元字符及文本字符所编写出的过滤条件;
正则表达式模式的实现或者能够搜索正则表达式都要用到正则表达式引擎

正则表达式引擎;
grep [OPTIONS] PATTERN [FILE…] PATTERN 模式

基本正则表达式元字符分为四种:字符匹配,次数匹配,位置锚定,分组及引用

字符匹配

元字符 含义
. 匹配任意单个字符
[] 匹配指定范围内的任意单个字符
[^] 匹配指定范围外的任意单个字符; 脱字符

POSIX字符

字符 含义
[[:digit:]] 数字
[[:lower:]] 小写字母
[[:upper:]] 大写字母
[[:alpha:]] 任意字母,不区分大小写
[[:alnum:]] 匹配任意字母或数字,不区分大小写
[[:space:]] 匹配任意空字符(包括空格)
[[:graph:]] 匹配除了空格以外的字符
[[:blank:]] 匹配空格或者制表符
[[:punct:]] 匹配所有标点符号
[[:print:]] 匹配任意可打印字符
[[:xdigit:]] 匹配所有的十六进制数

【例 1】

[root@admin ~]# grep "r..t" /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

此时要求:rt中间只匹配两个字母

[root@admin ~]# grep "r[[:alpha:]][[:alpha:]]t" /etc/passwd 
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

如果我们要在rt之间出现10个字母怎么办,我们可以指定次数指定

匹配次数:用在要指定其出现的次数的字符的后面,用于限制其前面字符出现的次数;默认工作于贪婪模式

次数匹配

字符 含义
* 匹配前面的字符任意次(前面的字符可以出现也可以不出现)
.* 匹配任意长度的任意字符(用来匹配字符)
? 匹配前面的字符零次或一次
+ 匹配前面的字符至少一次
{匹配次数} 指定匹配前面字符的次数
{最少匹配次数,} 指定匹配前面的字符至少的次数,多则不限
{,最多匹配次数} 指定匹配前面的字符最多次数,也可没有
{最少匹配次数,最多匹配次数} 指定匹配前面的的字符最少次数和最多次数

【例 2】

[root@admin ~]# cat text
abxy
aby
xxxxxy
yab
[root@admin ~]# grep "x*y" text
abxy        #匹配条件:y前面的x字母任意次(0次也算)
aby
xxxxxy
yab
[root@admin ~]# grep "x\?y" text
abxy		#匹配条件:y前面的x字母出现0次或1次
aby
xxxxxy    #这里只将x算作1次
yab
[root@admin ~]# grep "x\+y" text
abxy		#匹配条件:y前面的x字母出现至少1次
xxxxxy

【例 3】
以上无法控制次数,我们还可以精确次数匹配

匹配条件:y字母前x字母出现5次

[root@admin ~]# grep "x\{5\}y" text
xxxxxy

位置锚定

元字符 含义
^ 行首锚定,写在模式的最左侧;此字符后的任意内容必须出现在行首
$ 行尾锚定,写在模式的最右侧;此字符前的任意内容必须出现在行尾
<或\b 词首锚定,用于单词模式的左侧;其后面的任意字符必须作为单词的首部出现
<WORD> 匹配整个单词

模式匹配

^PATTERNS$ 用于模式匹配整行
^$ 匹配空行
^ [[:space:]]*$ 空行或包含空白字符的行

【例 4】
以行为单位查找符合条件的内容:

[root@admin ~]# cat text
root 123 root
rooter 123 reroot
123 root
123 reroot
rooter 123
root 123
dxk 111
[root@admin ~]# grep "root" text
root 123 root
rooter 123 reroot
123 root
123 reroot
rooter 123
root 123
[root@admin ~]# grep "^root" text
root 123 root
rooter 123 reroot
rooter 123
root 123
[root@admin ~]# grep "root$" text
root 123 root
rooter 123 reroot
123 root
123 reroot

【例 6】
以单词为单位查找符合条件的内容

单词:非特殊字符组成的连续字符(字符串)都称为单词

[root@admin ~]# grep "\<root" text #匹配单词以root开头
root 123 root
rooter 123 reroot
123 root
rooter 123
root 123
[root@admin ~]# grep "root\>" text #匹配单词以root结尾
root 123 root
rooter 123 reroot
123 root
123 reroot
root 123
[root@admin ~]# grep "\<root\>" text #匹配完整单词root
root 123 root
123 root
root 123

【例 7】
①显示/etc/passwd文件中不以/bin/bash结尾的行

[root@admin ~]# grep -v "/bin/bash" /etc/passwd

②找出/etc/passwd文件中的两位数或三位数

[root@admin ~]# grep "\<[0-9]\{2,3\}\>" /etc/passwd

③找出/etc/grub2.cfg文件中,以至少一个空白字符开头,且后面非空白字符的行

[root@admin ~]# grep "^[[:space:]]\+[^[:space:]]" /etc/grub2.cfg 

④找出"netstat -tan"命令的结果中以’LISTEN’后跟0、1或多个空白字符结尾的行

[root@admin ~]# netstat -tan | grep "LISTEN[[:space:]]*$" 

分组及引用

分组 \ ( \ ) 将一个或多个字符捆绑在一起,当做一个整体进行处理。分组括号中的模式匹配到的内容会被正则表达式引擎记录与内部的变量中,这些变量的命名方式为:\1,\2,\3…
后向引用 \1,\2,\3… 引用前面的分组括号中的模式所匹配到的字符,而非模式本身;被前面括号括起来的内容,后面可以使用一个字符将其引用; \1 表示引用第一个左括号以及与之对应的右括号所包括的所有内容

【例 8】
创建测试文件:

[root@admin ~]# vim loves.txt
[root@admin ~]# cat loves.txt
He loves his lover.
He likes his lover.
She likes her liker.
She loves her liker.

匹配条件: 在上面文件中找出每行中前后有一致的字段的行,例如:同是love 或者同是like的,用过观察,我们要得到的是第1、3行

[root@admin ~]# grep "l..e.*l..e" loves.txt 
He loves his lover.
He likes his lover.
She likes her liker.
She loves her liker.

这样做下来,发现并未达到预期效果,四行都输出出来了

于是我们可以进行分组并引用来达到目的:

[root@admin ~]# grep "\(l..e\).*\1" loves.txt 
He loves his lover.
She likes her liker.

可以通过下这个例子来进一步体会分组及引用的作用和优点:

[root@admin ~]# grep "^r..t.*r..t" /etc/passwd
root:x:0:0:root:/root:/bin/bash
rootp:x:14:50:FTP User:/var/ftp:/sbin/nologin
[root@admin ~]# grep "^\(r..t\).*\1" /etc/passwd
root:x:0:0:root:/root:/bin/bash

通配符和正则表达式区别:

  • 通配符
    它是由shell解析,并且一般用于匹配文件名,实际上就是shell解释器去解析的特殊符号,linux系统通配符有*、?、[]、[^]…
    一般出现在要shell命令或脚本中,匹配特定的文件名

  • 正则表达

    正则表达式是用来匹配字符串的,针对文件内容的文本过滤工具里,大都用到正则表达式,如vi,grep,awk,sed等

有时候,我们想让 通配符,或者元字符 变成普通字符,不需要使用它。那么这里我们就需要用到转义符。 shell提供转义符有三种:’’(单引号 ),""(双引号),\(反斜杠)

十、find命令

在指定的路径下查找指定文件的命令 find

用来在指定目录下查找文件。任何位于参数之前的字符串都将被视为欲查找的目录名
如果使用该命令时,不设置任何参数,则 find 命令将在当前目录下查找子目录与文件。并且将查找到的子目录和文件全部进行显示

find 命令有非常大的灵活性,可以向其指定丰富的搜索条件(如文件权限、属主、属组、文件类型、日期和大小等)来定位系统中的文件和目录。
此外,find 还支持对搜索到的结果进行多种类型的命令操作(使用-exec参数等)

find 命令接受一个或多个路径(paths)作为搜索范围,并在该路径下递归地搜索。即检索完指定的目录后,还会对该目录下的子目录进行检索,以及子目录下的子目录………直到到达目录树底部

工作特性: 查找速度略慢、精确查找、实时查找

用法: find [path] [option] [expression] [action]

默认情况下(不带任何搜索条件),find 命令会返回指定目录下的所有文件,所以常常需要通过特定的 expression 对结果进行筛选,即通过expression来指定查找条件

find 命令默认的 action 是将所有检索结果打印至标准输出。可以通过自定义 action ,让 find 命令对搜索到的结果执行特定的操作,默认为-print,打印出结果信息

常用选项:

  • -name:文件名
  • -i:忽略大小写
  • -perm:权限
  • -type 文件类型
  • -regex pattern:基于正则表达式模式查找文件,匹配是整个路径,而非其名
字母 含义
f 普通文件
d 目录
l 连链接件
b 块设备
s 套接字
c 字符设备
p 管道
  • -size +/-Number : 文档大小(+表示大于,-表示小于,单位 K/M/G …)
  • -user: 属主
  • -nouser: 无属主
  • -group:属组
  • -nogroup:无属组
  • -maxdepth:查找深度
  • -mindepth:最小深度
  • -newer File:查找更改时间比File文件新的文件
  • -mtime与 -mmin:都表示按照最后修改时间查找文件 +n n天前的文档 -n n天之内的文档
    ① mtime 以天为单位 (-mtime +n 表示n天前 ;-mtime -n表示n天内)
    ②mmin 以分钟为单位 (-mmin +n 表示n分钟前 ;-mmin -n表示n分钟内)
  • -atime与 -amin:都表示按照最后访问时间查找文件
    ①atime 以天为单位 (同上)
    ②amin 以分钟为单位(同上)
  • -ctime 与 -cmin:都表示按照创建的时间查找文件
    ① ctime 以天为单位(同上)
    ② cmin 以分钟为单位(同上)

action选项:

  • -print:输出至标准输出;默认的动作;
  • -ls:类似于对查找到的文件执行“ls -l”命令,输出文件的详细信息;
  • -delete:删除查找到的文件;
  • -fls File:把查找到的所有文件的长格式信息保存至指定文件中;
  • -ok COMMAND {} \ ; :对查找到的每个文件执行由COMMAND表示的命令;每次操作都由用户进行确认;
  • -exec COMMAND {} \ ; :对查找到的每个文件执行由COMMAND表示的命令;

在使用find命令时通常结合逻辑操作符来对查找结果进行筛选:

  • -a:逻辑与
  • -o: 逻辑或
  • !或 -not :逻辑非

【例 1】

列出当前目录和子目录下的所有文件

[root@localhost ~]# ls
anaconda-ks.cfg  file  install.log  install.log.syslog
[root@localhost ~]# find
.
./.bash_profile
./.lesshst
./install.log
./.cshrc
./file
./.viminfo
./.tcshrc
./anaconda-ks.cfg
./.bashrc
./install.log.syslog
./.bash_history
./.bash_logout

【例 2】

查找指定名称的文件
①在/下查找名为test的文件

[root@admin ~]# find / -name test
/root/dir/test
/usr/bin/test
/usr/lib/modules/3.10.0-1127.el7.x86_64/kernel/drivers/ntb/test
/usr/lib64/python2.7/test
/usr/lib64/python2.7/unittest/test

②也可以使用通配符

[root@admin ~]# find / -name te[sl]*
/boot/grub2/i386-pc/test.mod
/boot/grub2/i386-pc/test_blockarg.mod
/boot/grub2/i386-pc/testload.mod
……省略部分输出……

可以看到,当指定名称后就精确查找文件,该文件名必须是自己所指定的,而用通配符就可以进行模糊查找

如果不加path参数则默认在当前目录下查找

可以看到,所有的文件夹都会被递归地查找。所以,这是用于查找指定扩展名文件的一种非常强大的方式

如果我们尝试搜索 / 文件夹,也就是根目录,就会搜索整个文件系统,包括挂载的设备以及网络存储设备。所以慎用。当然,你随时可以通过按 Ctrl + C 来终止命令。

【例 3】

忽略大小写

在查找文件名时,忽略大小写往往非常有用。要忽略大小写,那么就需要使用-i和-name的结合使用

[root@admin ~]# find / -iname "test"
/root/dir/tEsT
/usr/bin/test
/usr/lib64/python2.7/unittest/test
/usr/share/perl5/Test
……省略部分输出……

建议总是用双引号或单引号来包围匹配模式(文件名参数),不这样做的话有时也能正常工作,有时也可能会产生奇怪的结果

【例 4】

限制目录查找的深度

find 命令默认会递归查找整个目录树,而这非常消耗时间和资源。好在目录查找的深度可以手动指定。例如我们只想查找一到两层以内的子目录,可以通过 maxdepth 选项来指定

#对比来看:
[root@admin ~]# find / -iname "file" #不指定深度会遍历所指定路径下的整个目录树
/sys/fs/selinux/class/file
/sys/fs/selinux/initial_contexts/file
/etc/file
/tmp/file
/tmp/dir/file
/tmp/file
/usr/bin/file
/usr/lib64/perl5/vendor_perl/file
/usr/lib64/perl5/auto/file
/usr/lib64/perl5/file
/usr/share/file
/usr/share/perl5/vendor_perl/file
/usr/share/perl5/file
[root@admin ~]# find / -maxdepth 3 -name "file"
/etc/file
/tmp/file
/tmp/dir/file
/tmp/file
/usr/bin/file
/usr/share/file
[root@admin ~]# find / -maxdepth 2 -name "file"
/etc/file
/tmp/file
/tmp/file

第二个示例中指定了 maxdepth 为3,也就是只查找当前最多为指定的目录,这里为/下的3层内的子目录中的所有文件

当我们只想在当前目录下查找,而不是查找整个目录树的时候,这个选项会特别有用。

与 maxdepth 选项相似,还有一个选项叫做 mindepth ,正如名字所表示的那样,它会至少到达第 N 层子目录后才开始查找文件

比如指定-mindepth 3,那么会从指定的目录的第三层子目录后才去查找,之前的不予查找

【例 5】

反向查找

除了查找满足条件的文件之外,我们还可以查找不满足条件的所有文件。当我们知道要在查找中排除哪些文件时,这个选项就能发挥作用了

在/etc下查找名称不是test的文件
[root@admin ~]# find /etc -not -name "test"
#也可以使用感叹号 ! 来代替 -not
[root@admin ~]# find /etc ! -name "test"

【例 6】

只查找指定类型的文件

①在/下查找名为test的普通文件

[root@admin ~]# find / -type f -name "test"

②在/下查找名为test的目录

[root@admin ~]# find / -type d -name "test" 

③在/下查找名为test的链接文件

[root@admin ~]# find / -type l -name "test" 

【例 7】

同时在多个目录下查找

#在/etc和/tmp下查找名为test的链接文件
[root@admin ~]# find /etc /tmp -type l -name "test" 

【例 8】

查找隐藏文件

在Linux系统中,隐藏文件的名字以英文的句号开头,即 . 所以要列出隐藏文件,只需加上简单的文件名过滤条件就行了

[root@admin ~]# find / -type f -name ".test*" 

【例 9】

查找指定权限的文件

通过指定 perm 选项,我们可以查找具有特定权限的文件

[root@admin ~]# find / -perm 444 

【例 10】

查找属于特定用户的文件

①查找当前目录下,属于 bob 的文件

[root@admin ~]# find . -user bob 

② 查找属于特定用户组的文件

[root@admin ~]# find . -group root 

③查找当前系统上没有属或属组,且最近一周内曾被访问过的文件或目录

[root@admin ~]# find / \( -nouser -o -nogroup \) -atime -7 -ls

【例 11】

基于日期和时间的查找

除了以上的查找条件外,另外一个查找条件就是文件的修改和访问时间(日期)。当我们想要找出哪些文件在某段时间内被修改的时候,这个查找条件将会非常方便

①查找过去的第50天被修改过的文件

[root@admin ~]# find . -mtime 50 

② 查找过去的 50天内被访问过的文件

[root@admin ~]# find . -atime 50 

③ 查找某段时间范围内被修改过内容的文件

[root@admin ~]# find . -mtime +50 -mtime -100 

④查找过去的60分钟内状态发生改变的文件

[root@admin ~]# find . -cmin -60 

⑤查找过去的 1 小时内被修改过内容的文件

[root@admin ~]# find . -mmin -60 

⑥ 查找过去的 1 小时内被访问过的文件

[root@admin ~]# find . -amin -60 

【例 12】
基于文件大小的查找

①查找指定大小的文件

[root@admin ~]# find . -size 10M 

②查找大小在一定范围内的文件

[root@admin ~]# find . -size +50M -size -100M #大于50M小于100M

【例 13】

查找空文件和空目录

①查找空文件:

[root@admin ~]# find / -type f -empty

②查找空目录:

[root@admin ~]# find / -type d -empty

【例 14】

find 还支持对搜索到的结果进行多种类型的命令操作

-ok COMMAND {} ; :对查找到的每个文件执行由COMMAND表示的命令;每次操作都由用户进行确认;
-exec COMMAND {} ; :对查找到的每个文件执行由COMMAND表示的命令

①查找名为test的链接文件并显示其长信息

[root@admin ~]# find /etc -name "pass[a-z][a-z]" -exec ls -l {} \;
-rw-r--r--. 1 root root 1088 7月  20 21:50 /etc/passwd
-rw-r--r--. 1 root root 188 4月   1 11:57 /etc/pam.d/passwd

②查找当前目录下的空普通文件并强制删除

[root@admin ~]# find . -type f -empty -exec rm -rvf {} \; 
已删除"./dir/test"
已删除"./dir/dd/111"
已删除"./file3"
[root@admin ~]# find . -type f -empty -ok rm -rf {} \;
< rm ... ./f1 > ? y     #即使是rm -f强制删除也需要进行询问
< rm ... ./f2 > ? y  
< rm ... ./f3 > ? y
< rm ... ./f4 > ? y
[root@admin ~]# 

【例 15】
在当前目录下查找更改时间在比/tmp/test.baklog2012.log文件新的文件

[root@admin ~]# find . -newer /tmp/test.bak 

【例 16】结合多个查找条件

可以同时使用多个查找条件来指定文件名并排除某些文件

①在/目录下查找以file开头并且不含.txt扩展名的文件

[root@admin ~]# find / -name "file*" -not -name "*.txt"

②查找/usr目录下不属于root, bin或dxk的所有文件或目录;用两种方法;

[root@admin ~]# find /usr -not -user root -a -not -user bin -a -not -user dxk
/usr/share/polkit-1/rules.d
[root@admin ~]# ll -d /usr/share/polkit-1/rules.d
drwx------. 2 polkitd root 6 4月   1 12:07 /usr/share/polkit-1/rules.d
#
[root@admin ~]# find /usr -not \( -user root -o -user bin -o -user dxk \) -ls
67597266    0 drwx------   2 polkitd  root            6 4月  1 12:07 /usr/share/polkit-1/rules.d

③查找/etc目录下大于1M且类型为普通文件的所有文件

[root@admin ~]# find /etc -size +1M -type f -exec ls -lh {} \; 
-r--r--r--. 1 root root 8.0M 6月  29 17:14 /etc/udev/hwdb.bin
-rw-------. 1 root root 3.8M 4月   1 12:29 /etc/selinux/targeted/active/policy.kern
-rw-r--r--. 1 root root 1.4M 4月   1 12:35 /etc/selinux/targeted/contexts/files/file_contexts.bin
-rw-r--r--. 1 root root 3.8M 4月   1 12:29 /etc/selinux/targeted/policy/policy.31

【例 17】
基于正则表达式的查找

[root@admin ~]# find / -regex "/etc/pa.*d$"
/etc/passwd
/etc/pam.d
/etc/pam.d/crond
/etc/pam.d/vmtoolsd
/etc/pam.d/sshd
/etc/pam.d/passwd

find 命令是直接在硬盘中进行搜索的,如果指定的搜索范围过大,find命令就会消耗较大的系统资源,导致服务器压力过大。所以,在使用 find 命令搜索时,不要指定过大的搜索范围

十一、which命令

which 查找可执行的文件

在PATH变量指定的路径中,搜索某个系统命令的位置,并且只返回第一个搜索结果。也就是说,使用which命令,就可以看到某个系统命令是否存在,以及执行的到底是哪一个位置的命令(搜索命令所在路径及别名)

用法: which [options] [–] COMMAND […]

常用选项:
-a:返回在PATH路径下找到的所有结果

【例 1】

[root@admin ~]# which pwd
/usr/bin/pwd
[root@admin ~]# which find
/usr/bin/find

which 是根据使用者所配置的 PATH 变量内的目录去搜索可执行文件,所以,不同的 PATH 配置内容所找到的命令是不一样的

【例 2】

[root@admin ~]# which mv
alias mv='mv -i'/usr/bin/mv

alias 这就是所谓的『命令别名』,意思是输入 which 会等於后面接的那串命令

[root@admin ~]# which pwd
/usr/bin/pwd
[root@admin ~]# pwd
/root
[root@admin ~]# /usr/bin/pwd
/root

【例 3】
这里我们自己创建一个和系统命令pwd名字一样的pwd命令,不过功能不一样。并将它放入PATH变量的路径下

[root@admin ~]# vim pwd
[root@admin ~]# cat pwd
echo this is test
[root@admin ~]# chmod +x pwd
[root@admin ~]# /root/pwd
this is test

放于系统pwd命令在PATH变量的路径之后

[root@admin ~]# which pwd
/usr/bin/pwd
[root@admin ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@admin ~]# mv pwd /root/bin

which在PATH变量指定的路径中,搜索某个命令的位置,并且只返回第一个搜索结果
which -a可以返回所有的搜索结果:

[root@admin ~]# which pwd
/usr/local/bin/pwd
[root@admin ~]# which -a pwd
/usr/local/bin/pwd
/usr/bin/pwd

十二、whereis命令

whereis 查看文件的位置

whereis命令只能用于搜索程序名,而且只搜索二进制文件(选项-b)、man说明文件(选项-m)和源代码文件(选项-s),如果省略参数,则返回所有信息。搜索文件所在的路径以及帮助文档所在的位置

和 find相比,whereis查找的速度非常快,这是因为linux系统会将系统内的所有文件都记录在一个数据库文件中,当使用whereis和下面即 将介绍的locate时,会从数据库中查找数据,而不是像find命令那样,通过遍历硬盘来查找,效率自然会很高

用法: whereis [选项] 文件

常用选项:

  • -b:只查找可执行文件
  • -m:只查找帮助文件
[root@admin ~]# whereis pwd
pwd: /usr/bin/pwd /usr/share/man/man1/pwd.1.gz
[root@admin ~]# whereis -b pwd
pwd: /usr/bin/pwd
[root@admin ~]# whereis -m pwd
pwd: /usr/share/man/man1/pwd.1.gz

十三、locate命令

locate 命令用来查找文件或目录

locate命令要比find -name快得多,因为它不是搜索具体目录,而是搜索一个数据库/var/lib/mlocate/mlocate.db 。这个数据库中含有本地所有文件信息。Linux系统自动创建这个数据库,并且每天自动更新一次

因此,我们在用whereis和locate 查找文件时,有时会找到已经被删除的数据,或者刚刚建立文件,却无法查找到,原因就是因为数据库文件没有被更新。为了避免这种情况,可以在使用locate之前,先使用updatedb命令,手动更新数据库

整个locate工作其实是由四部分组成的:

  • /usr/bin/updatedb 主要用来更新数据库,通过crontab自动完成的

  • /usr/bin/locate 查询文件位置

  • /etc/updatedb.conf updatedb的配置文件

  • /var/lib/mlocate/mlocate.db 存放文件信息的文件

工作特性: 查找速度快、模糊查找、非实时查找

用法: locate [OPTION]… PATTERN…

常用选项:

  • -b:只匹配路径中的基名;
  • -c:统计出共有多少个符合条件的文件;
  • -r:BRE 基本正则表达式
  • -i, --ignore-case 忽略大小写
  • -q, --quiet 安静模式,不会显示任何错误讯息
  • -r, --regexp REGEXP 使用基本正则表达式
  • -n Num:限制搜索结果的数量

安装locate:

[root@localhost ~]# yum install mlocate -y

locate命令是将文件位置信息缓存到var/lib/mlocate/mlocate.db 数据库文件中的,所以首次安装locate命令后,先执行updatedb命令,更新mlocate.db的数据库文件
然后再用locate命令执行文件查找操作

【例 1】
搜索etc目录下所有以my开头的文件

[root@admin ~]# locate /etc/my
/etc/my.cnf
/etc/my.cnf.d
/etc/my.cnf.d/mysql-clients.cnf

【例 2】
新增的文件无法locate,使用updatedb

[root@admin ~]# touch new.txt
[root@admin ~]# locate new.txt 
[root@admin ~]# updatedb
[root@admin ~]# locate new.txt 
/root/new.txt

【例 3】
统计出共有多少个符合条件的文件

[root@admin etc]# locate -c .bashrc
7

限制搜索结果的数量

[root@admin etc]# locate -c .bashrc
7
[root@admin etc]# locate -n 5 .bashrc
/etc/skel/.bashrc
/home/Bob/.bashrc
/home/dxk/.bashrc
/home/eddy/.bashrc
/home/eddydel/.bashrc

【例 4】
-r 正则表达式

[root@admin ~]# locate -r /etc/"\<pa\+s*.*d$"
/etc/pam.d
/etc/passwd
/etc/pam.d/crond
/etc/pam.d/passwd
/etc/pam.d/sshd
/etc/pam.d/vmtoolsd

文件搜索命令 which、whereis、find、locate 的区别:

1.which
which 命令用于查找可执行文件。作用是:在PATH变量指定的路径中,搜索某个系统命令的位置,并且返回第一个搜索结果。在使用which进行查找时,查找目标需要提前配置到环境变量中,否则查不出来

2.whereis
whereis命令用于搜索程序的二进制文件(-b),源代码文件(-s)或帮助文档(-m)

3.find
find是覆盖最全面的查找工具,但它在硬盘上遍历查找,非常消耗硬盘的资源,而且效率也很低,优先使用其他几个

4.locate
相当于find -name,但它是从数据库(/var/lib/locatedb)中查找,效率要比find高很多。
Linux系统自动创建locatedb,每天自动更新一次,所以使用locate命令查不到最新变动过的文件。为了避免这种情况,可以在使用locate之前,先使用updatedb命令,手动更新数据库。

  相关解决方案