linux 文件查找与打包

1. 实验介绍

1.1 实验内容

在上一节的内容中我们介绍了文件的属性,而在本实验中,我们将会根据这些属性值以及一些其他的条件参数来带领大家学习如果查找符号指定条件的文件。并且会简单介绍文件打包的内容。

1.2 实验知识点

在文件查找部分,我们将向你展示如何使用下面列出的条件去查找一些文件:

  • 文件名包含某些文本或者匹配某个模式
  • 链接类型文件
  • 该文件在一段时间内被使用
  • 该文件的大小在一定范围内
  • 该文件属于某些类型(普通文件,目录等)
  • 该文件属于某个用户组
  • 该文件有一定访问权限
  • 或以上的一些组合

在打包部分,将简单介绍:

  • gzip 命令
  • tar 命令

2. find

find 命令查找一个文件是在目录层次下搜索。并且会打印所找到文件的有关信息,find 的使用情况如下所示:

find [path...][expression]

这里的 [expression] 有下面四种类型组成:

  • options 配置项

    影响整体的操作

  • tests 测试项

    返回一个 true 或 false 值,这些取决于文件的属性

  • actions 操作项

    根据对应的操作

  • operators 运算符

    连接其他的参数

例如下面的这个例子,查找 /etc 目录下,文件大小大于 100k 的文件

$ sudo find /etc/ -size +100k

这里需要说明的是,对于数值参数,可以指定为:

  • +n 大于 n
  • -n 小于 n
  • n 等于 n

2.1 文件名

通配符

对于常用 findlocate 命令来说,可以通过一个包含特殊字符串的 shell 模式(Shell Pattern)去比较文件名或者部分文件名。

这里的特殊字符串又被称为 通配符(wildcards),通配符是一些特殊字符,又被称为元字符(metacharacters),在后面的内容中我们统一称为 通配符

下面我们介绍常见的 shell pattern 中用到的通配符:

  • *:匹配0个或多个字段
  • ?:匹配任意一个字符
  • [string]:匹配 string 字符串中的任意一个字符,如 [abc] 匹配 abc 三个字符中的任意一个,[a-z0-9] 匹配小写字母和数字。
  • \:移除特殊字符的特殊含义,转义

基础名称模式

  • -name:指定名称
  • -iname:置顶名称忽略大小写

基础名称是指删除文件的前导目录,如果能够匹配到,则为 True,我们知道 find 会打印所找到文件的有关信息,但是默认情况下,find 命令只会打印符合给定条件的文件名称到标准输出下。

如下的简单示例,查找 /usr 目录下以子母 r 开头,.txt 结尾的文件:

$ find /usr -name "r*.txt"

* 代表任意字符,然后 .txt 。则以 .txt 结尾的文件,需要注意的是,为了跟一般命令参数作区分,在使用通配符的时候,通常需要使用引导

如下所示,使用 -iname 参数,不区分大小写。

$ find /usr -iname "r*.txt"

我们都知道,在当前目录下,以 . 号开头的文件为隐藏文件,这里需要说明的是,根据使用的版本不同,有的可能会默认匹配到 . 符号开头的文件。如下,查找,当前目录下,文件名以 ter 开头 zsh 结尾的文件:

$ find -name "ter*zsh"

我们可以看到,在实验楼的环境中是支持查找以 . 开头的文件的。

全名模式

  • -path:指定路径
  • -wholename:功能同 -path 类似

-name 一样,-path-wholename 也有对应的忽略大小写的参数,即 -ipath-iwholename

在使用 -path 参数时,全名 指的是从起始点开始的 全名,例如, /usr 目录下有 bin 目录,如果我们在 bin 目录下,查找是否有路径为 bin/python 的文件,首先切换到 /usr 目录:

$ cd /usr

此时,当前目录为 /usr

如下所示,-path 的其实路径应为 /usr/bin,这里是 bin,所以为空

$ find /usr/bin -path bin/python

如下所示,-path 的起始路径应为 bin,所以得到结果

$ find bin -path bin/python

  • -regex
  • -iregex

正如 regex 的中文释义一样,这里代指 正则表达式,与上面所说的通配符并不一样。-regex 可以通过正则表达式去匹配,并且我们可以通过 -regextype 选项去指定正则表达式的类型,常用的选项有(emace,posix-awk,posix-egrep),如使用 -regextype posix-awk,代表与 POSIX awk 命令兼容的正则表达式。

2.2 链接

符号链接

符号链接(symbolic links)是引用其他文件的名称。find 命令对符号链接的处理方式一般未检查链接本身或者检查链接所指向的文件。默认情况下,find 检查符号链接本身,即默认的 -P 选项。如果想要检查连接所指向的文件,可以使用 -L 参数。而 -H 参数,则代表除了处理命令行参数之外,不遵循符号链接。需要注意的是 -P-H-L 参数都必须在命令行上使用文件名之前指定此选项。

例如,/usr/bin/python 文件就是一个符号链接,我们可以看到该文件指向的是 python2.7

$ ls -l /usr/bin/python
lrwxrwxrwx 1 root root 9 Dec 21 2013 /usr/bin/python -> python2.7

  • -lname
  • -ilname

-lname 属于测试项,用于匹配文件是否为一个符号链接,与对应的 -ilname 参数的区别同上面的大多数参数一样,不去分大小写。

如下所示,我们分别查找 /usr/bin 目录下文件名包晗 python3 的文件,和使用 -lname 参数,对得到的结果进行筛选,仅列出符号链接:

$ find /usr/bin -name "*python3*"

$ find /usr/bin -lname "*python3*"

硬链接

硬链接允许多个名称引用相同的文件。符号链接有时候也称为软连接,我们可以简单的理解为,符号连接记录着被链接文件的地址,而对于硬链接(hard links)而言,则是对于被链接文件的复制。

但是这里所说的复制并不是真正的复制,而是链接文件和被链接文件的内容一致的,就如同我们使用多个编辑器打开同一个文件一样,对文件作出修改后,其他编辑器上的内容也会发生改变。所以这里我们也可以理解为一个文件可以有多个文件名,而这个文件名就是硬链接。

这里我们创建几个文件用作演示:

$ touch file1
$ echo "test_hard_link" > file1

# 创建文件 file1 的硬链接 file2
$ ln file1 file2

# 创建文件 file1 的硬链接 file3
$ ln file1 file3

现在我们创建了一个文件 file1,并且使用创建硬链接的方式,创建了 file2file3。这个时候,这三个文件都是指向的同一个文件,我们可以通过查看三个文件的内容,以及修改文件内容来证实刚才的结论。

  • -samefile 测试项

如下所示,我们使用 -samefile 参数来得到当前目录下和 file1 文件 incode 相同的硬链接。

$ find -samefile file1

  • -inum n 测试项

    文件的 inodenn 是数值参数,可以是 -n+n

每个 inode 都是一个号码,我们可以通过数值参数 n 来匹配相应的文件。如下所示,使用命令查看:

$ ls -i

例如,示例中所示,file1file2file3inode 号都为 159160 (自行操作时会与上述不一致),所以我们查找当前目录下 inode 号为 159160 的文件。

$ find -inum 159160

  • -links n 测试项

    文件有 n 个硬链接,n 是数值参数,可以是 -n+n

除此之外,硬链接的数目,也可以作为 find 的参数进行使用我们可以查看文件的硬链接数目,来判断与我们使用的 -inum 参数得到的结果是否一致。如下所示,匹配当前目录下硬链接数为 3 的文件。

$ find -links 3

从输出信息可以看到我们定义的 file(123) 文件的硬链接数和数目 3 一致。

$ ls -li

2.3 Time

每个文件都有三个时间戳,分别为:

  • 访问(上一次访问文件的时间)
  • 更改(改变文件或其属性的时间)
  • 修改(修改文件内容的时间)

注:部分系统还会有文件的创建时间,例如(windows)。

下面我们将介绍 find 命令中使用这些时间戳的参数

  • -atime n 测试项

文件上一次访问时间是在 n*24 小时之前。需要注意的是,如果我们使用的 n 值为 0 ,则向下取整,意味着距离上一次访问时间不足 24 小时。同样 n 是数值参数,可以是 -n+n

  • -ctime n 测试项

    这里代表的是状态的改变

  • -mtime n 测试项

    这里代表文件内容被修改

为了方便记忆,我们可以将英文单词关联起来,这里的 aaccesscchange,而 m 则是 modify

除了用 24 小时技术之外,我们还可以细化到 minute 多少分钟,与上面对应的参数应该为:

  • -amin n
  • -cmin n
  • -mmin n

如下示例,我们查找当前目录下,修改文件的时间在 5 分钟到 24 小时之间:

$ find -mtime 0 -mmin +5

根据具体时间,可能会有不同,所以这里未给出运行截图。

2.4 Size

文件的大小也是文件的属性中很重要的一栏,

  • -size n[bckwMG]

这里的 n 是数据参数,b 代表块 blockc 代表字节, k 代表 1024 字节,即kb,w 代表字符数量(2-byte 的字符),M 代表兆字节,G 代表千兆字节。

例如,查找当前目录下的大于 100k 的文件。

$ find -size +100k

2.5 Type

这里我们仅介绍一些常用的文件类型

  • -type c 测试项

这里代表 c 可以是以下的文件类型(仅列出部分文件类型):

  • d 目录
  • f 普通文件
  • l 符号链接

例如,查找 /etc 目录下,文件大小大于 30k 并且为普通文件的文件:

sudo find /etc -type f -size +30k

2.6 Owner

  • -user uname
  • -group gname

如上所示,uname 代表文件所属用户的名字,gname 代表文件所属组的名字

  • -uid n
  • -gid n

这里分别代指用户 id 和 组 id

如下所示,分别查找当前目录下所属用户为 shiyanlou 的文件,以及所属用户为 root 的文件

$ find -user shiyanlou

# root 用户的 id 为 0
$ find -uid 0

2.7 File Mode Bits

文件有对应权限

  • -readable 测试项

    可读

  • -writable 测试项

    可写

  • -executable 测试项

    可执行

对于上面可能会用到的三个参数,针对的都是当前的系统用户去判断对文件是否有对应的权限

例如。查看当前用户,对 /etc 目录有可执行的权限并且文件名以 a 结尾的文件:

$ find /etc -executable -name "*a"

3. locate

除了使用 find 命令外,我们也可以使用 locate 命令来实现快速查找。但是不同于 find 命令,locate 命令其实是在一个保存有系统中所有文件名和目录名的数据库中去查找。而数据库中的内容并不是实时更新的,该数据库的更新操作可以使用 updatedb 命令来执行。

如下,我们查找文件名中含有 /usr/bin/python 的文件

$ locate /usr/bin/python

也可以使用 —basename 参数,查找基础名称,如下所示,查找基础名称中带有 shiyanlou 的文件

$ locate --basename shiyanlou

4. whereis

whereis 命令同 locate 类似,也是在一个保存有系统中所有文件名和目录名的数据库中去查找。不同的在于 whereis 命令查找的是二进制文件,源,或者 man 手册的文件。

下面我们将会介绍一些该命令的常用参数并简单示例:

  • -f 定义搜索范围
  • -b 仅搜索二进制文件
  • -m 仅搜索 man 文件
  • -s 仅搜索源

例如,搜索 python 相关的帮助手册:

$ whereis -m python

5. which

which 命令一般用于查找 shell 命令的完整路径。该命令在环境变量 PATH 中列出的目录中搜索可执行文件或脚本进行匹配查找。

常用的如 -a 参数,代表列出所有匹配的查找结果,而不仅仅是第一个。

示例如下,查找 python 可执行文件的路径:

$ which python

6. 文件打包和解压

在 linux 中,支持的压缩命令是非常多的,并且不同的压缩命令所使用的压缩机制也不尽相同,再加上很多比较老的压缩方式如 zip 等已经不常用了。不同于文件查找的描述,对于这一部分的内容,我们仅简单介绍两个常用的操作。

6.1 gzip

gzip 命令用于对文件进行压缩,生成的压缩文件会以 .gz 结尾。而对应的解压缩的命令则是 gunzip。两个命令的使用格式情况如下:

gzip -v file
gunzip -v file

简单示例,这里我们创建一个 file4 文件:

$ touch file4
$ gzip file4
$ ls

结果如下图,file4 文件消失,取而代之的是被压缩过的文件 file4.gz:

解压文件 file4:

$ gunzip file4.gz

6.2 tar

tar 是用于创建文件档案的命令行工具,多用于备份文件。顾名思义,tar 命令可以将一系列的文件打包到一个大文件中,也可以将大文件解包以恢复数据。下面,我们将介绍 tar 的常用参数,并简单示例。

tar 命令的格式大致如下

tar [OPTION...][FILE]
  • -c--create:创建一个文档
  • -r:将文件附加到档案文件末尾
  • -z--gzip: 指定 gzip 格式
  • -v--verbose:显示文件处理的详细过程
  • -f:指定档案文件名称
  • -x:还原档案文件

首先,我们删除之前创建的 file2,file3,因为他们都是指向的同一个文件。然后再次使用 touch 命令创建 file2file3

$ rm file2 file3
$ touch file2 file3

接着我们使用 tar 命令将四个文件归档都 test.tar 中:

$ tar -cvf test.tar file1 file2 file3 file4

$ ls

这时我们可以看见 test.tar 已经创建成功,接着我们删除四个文件,并从test.tar 恢复文件

$ rm file1 file2 file3 file4

$ ls

$ tar -xvf test.tar

7. 总结

本节实验中我们学习了一些常用的查找文件的方式和简单压缩及打包文件,但是对于实际操作还是需要自己动手操作才能保证有所收获。

results matching ""

    No results matching ""