[TOC]
# 文件及目录操作相关命令
## 文件、目录及路径的概念
> 说到文件、目录其实大家都会有大概的一个概念,比如记录日记的一页纸是一个文件、记录今天行程的便签是一个文件,而为了避免文件乱丢乱放找不到,我们会将这些文件都收纳到了不同的文件夹中保存,这就是我们日常生活中的对文件和文件夹的理解,那么在计算机中也是类似的道理。
### 什么是文件
>专业的定义是: 文件是在逻辑上具有完整意义的信息集合,它有一个文件名以供标识,文件名是以字母开头的字母数字串。
> 首先是一个信息集合,比如我们编写的办公文档、命令程序,他们都是信息的集合,其次是逻辑上具有完整意义,能够完整的表达这个文件的信息价值,比如命令程序文件可以被运行,文档可以被文档解析软件正确解析,一个被损坏的文件是布局有完整意义的,例如我们下载的视频文件因为没有下载完成而无法被解析成功,下载途中的图片无法被图片软件解析等等。
文件是文件系统中对信息数据管理的基本单位,文件是具有格式的,不同的文件格式在操作系统中表示不同的意义。
例如: 一个图片文件与一个文本文件的文件格式是不同的,在Windows系统中通常是通过文件扩展名`.jpg`和`.txt`区分,Linux系统下也是可以通过文件名后缀识别不同文件格式的。
### 什么是目录(文件夹)
`目录`也叫做`文件夹`,用来对文件数据的分类存放,这样不同的目录下可以分别存放不同类型的数据,比如`/etc`目录用于存放配置类文件数据,`/usr/bin/`存放的都是可执行程序文件数据,你可以自定义`视频`或者`图片`等目录来分类你的个人文件数据。
### 根目录
Unix/Linux系统的目录结构是从`/`开始的树形结构(也叫作`root目录`或根目录,以后了解文件系统时会深入了解)。目录之间使用斜杠`/`分隔,而不是Windows中的反斜杠`\`。root目录`/`下有子目录,如/usr、/home、/tmp等等。
![Linux目录的树形结构](https://img.kancloud.cn/3a/60/3a600a89be6dcd0e46a2683d728d857c_700x234.jpg)
### 什么是路径(绝对路径与相对路径)
当我们想要访问某一个目录或文件时,首先要知道它的存放位置,这个位置就是存放的`路径`,路径分为两种:`绝对路径`和`相对路径`。
- `绝对路径`就是以`/`根目录开始表示的路径,无论我们当前的工作路径在哪里,都可以使用绝对路径正确访问。
- `相对路径`就是不以`/`开始表示的路径,例如`code/python_test.py`、`./code/github/README.md`或者`../config/test.conf`,当我们更换了`当前工作目录`后需要同时修改`相对路径`信息才可以再次正确访问目录或文件。
注意: 当我们使用`相对路径`时,如果不以`..`或`.`开头需要在`$PATH`环境变量中添加`.`当前工作目录才可以正确使用`相对路径`,例如我们想在当前目录下执行一个`hello.sh`脚本:
```sh
$ echo $PATH
/home/user/bin:/usr/local/bin:/usr/bin:/bin
$ hello.sh
hello.sh 命令没找到
$ ./hello.sh
hello world!
$ export PATH=$PATH:.
$ echo $PATH
/home/user/bin:/usr/local/bin:/usr/bin:/bin:.
$ hello.sh
hello world!
```
### 重要的目录
下面这些目录需要重点介绍。
- `/bin`目录中存放的是可执行文件,包括大部分基础的Unix命令(如ls和cp)。该目录中的大部分是由C编译器创建的二进制文件,还有一些现代系统的shell脚本文件。
- `/dev`目录中是设备文件,磁盘、输入输出设备等等。
- `/etc`目录存放重要的系统配置文件,如用户密码文件、启动文件、设备、网络和其他配置文件。
- `/home`目录中是用户的个人目录。大多数Unix/Linux系统都遵循这个规范。
- `/lib`目录中是供`32位`可执行程序使用的各种代码库。代码库分为两种:静态库和共享库。`/lib`目录中一般只有共享库。
- `/lib64`目录中是供`64位`可执行程序使用的各种代码库。
- `/usr`目录存放着许多Linux系统文件。`/usr`目录中的很多子目录目录名和root目录上的相同(如`/usr/bin`和`/usr/lib`等等),你可以在`/bin`目录下看到很多命令其实是软链接到了`/usr/bin`目录下的命令的(为了让root文件系统占用尽可能少的空间,也是方便命令程序的更新管理)。
- `/proc`目录中通过一个可浏览的目录与文件接口来存放系统相关信息,比如当前运行的进程和内核的信息。Linux上这个目录的一大部分子目录结构相比其他Unix系统要特别一些,但其他Unix系统大多也有类似的特性。/proc目录中包含了当前正在运行的进程的信息以及一些内核参数。
- `/sbin`目录中是可执行的系统文件,这些可执行文件用来管理系统。普通用户一般不需要使用,许多命令只能由`root`用户运行。
- `/tmp`目录存放的是临时文件。所有用户对该目录都有读和写的权限,不过可能对别人的文件没有权限。许多程序会使用这个目录作为保存数据的地方,但如果数据很重要的话请不要存放在/tmp目录中,因为很多系统会在启动时清空/tmp目录,甚至是经常性地清理这个目录里的旧文件。也注意不要让/tmp目录里的垃圾文件占用太多的硬盘空间。
- `/var`目录是程序存放运行时信息的地方,如系统日志、用户信息、缓存和其他信息。(你可能会注意到这里有一个子目录/var/tmp,和/tmp不同的是,系统不会在启动时清空它。)
- `/boot`目录存放内核加载文件。这些文件中存放Linux在第一次启动时的信息,之后的信息并不保存在这里。
- `/opt`目录一般存放第三方软件,许多系统并没有这个目录。
## 操作文件及目录的命令
> 文件及目录操作命令可能是我们使用最多的命令了,因为我们需要跟文件和目录打交道最多。所以掌握这些命令算是学习Linux系统的基础。
### Shell通配符
shell可以使用`通配符`来匹配文件名和目录名。其他的操作系统也有通配符这个概念。当我们`对文件名或目录名不太确定具体值`或者`批量操作文件或目录`时就可以使用通配符来匹配。
通配符有:
- `*` : 匹配0个或多个任意字符(包括字母、数字和符号)。
- `?` : 匹配`1`个任意字符(包括字母、数字和符号)。
举例来说:
1. 列举当前目录所有以`A`开头的文件或目录: `ls -ld A*`
2. 列举当前目录所有名字格式为`?ata.txt`的文件或目录: `ls -ld ?ata.txt`(可能是Data.txt或data.txt等等)
### 查看当前目录内容-ls
> 这是我们使用最多的一个命令了,因为在操作目录下文件之前先要知道木对应目录下有哪些文件或目录。
下面是查看当前目录信息的示例:
```sh
# 在一行列举当前目录下的所有文件及目录(不包括以.开头的隐藏文件)
$ ls
# 逐行列举当前目录下的所有文件及目录(不包括以.开头的隐藏文件)的详细信息
$ ls -l
# 逐行列举当前目录下的所有文件及目录(包括以.开头的隐藏文件)的详细信息
$ ls -al
```
我们还可以使用`-t`参数按文件最后修改时间信息排序(先列举新文件),使用`-r`参数逆向排序(先列举旧文件),如下:
```sh
$ ls -tl
$ ls -trl
```
参数`-d`,可以防止进一步列举指定目录内的信息,减少递归深入访问目录层次:
```sh
$ ls -ld ./*
drwxr-xr-x 2 zioer users 6 9月 8 00:42 ./公共
drwxr-xr-x 2 zioer users 6 9月 8 00:42 ./模板
drwxr-xr-x 9 zioer users 267 12月 8 22:39 ./视频
drwxr-xr-x 3 zioer users 4096 12月 14 15:42 ./图片
drwxr-xr-x 9 zioer users 238 12月 20 15:57 ./文档
drwxr-xr-x 8 zioer users 4096 12月 19 12:45 ./下载
drwxr-xr-x 2 zioer users 6 9月 8 00:42 ./音乐
drwxr-xr-x 2 zioer users 73 12月 10 11:14 ./桌面
```
### 访问目录-cd
`cd`命令用来设置`当前工作目录`。`当前工作目录`是指你的进程和shell当前所在的目录。
```sh
$ cd /tmp
```
如果不带dir参数,cd命令会返回你的`默认工作目录`(`$HOME`变量指定目录),指的是你登录系统后进入的目录。
在`Linux`系统中:
- 符号`.`表示`当前目录`。
- 符号`..`表示当前目录的`上级目录`(也叫父目录)。
- 符号`~`表示默认工作目录(`$HOME`目录)。
- 符号`-`表示切换上次访问的目录(`$OLDPWD`环境变量对应的目录)
### 查看当前目录的绝对路径-pwd
这个命令没有任何参数,执行后显示当前工作目录的绝对路径:
```sh
$ pwd
/tmp
```
### 创建目录-mkdir
最简单的目录创建命令:
```sh
$ mkdir ./download
$ mkdir ./download/{video,image,software}
```
上面新建两级目录,执行了两次`mkdir`命令,可以使用`-p`参数批量创建多级子目录(如果其中子目录不存在就创建):
```sh
$ mkdir -p ./download/{video,image,software}
```
### 删除目录-rmdir
```sh
$ rmdir ./download/{video,image,software}
$ rmdir ./download
```
同`mkdir`一样,可以使用`-p`参数递归删除子目录:
```sh
$ rmdir -p ./download/{video,image,software}
```
> 注意:`rmdir`命令删除目录时需要先清空目录内的文件或子目录,否则会`目录非空`报错信息。
> 如果想删除非空目录需要使用`rm -rf `命令删除,但是前提是你一定清楚要删除的是什么内容。
### 移动或重命名文件及目录命令-mv
将目录从一个路径`移动`到另一个路径下,或者将一个目录名`重新命名`为另一个目录名,这时我们会使用到`mv`命令
```sh
$ mv 源文件或目录 新目录名
$ mv 源文件 目标文件
```
如果我们想把多个文件存放到一个目录下的命令如下:
```sh
$ mv 文件1 文件2 ... 目标目录
```
如果可能会有文件名同名时,而你的确想要覆盖掉`目标目录`的文件时,可以使用`-f`选项参数强制用新文件覆盖掉`目标目录`下原有的文件。
```sh
$ mv -f 文件1 文件2 ... 目标目录
```
> 说明: 可能你会发现`mv`命令有时候移动文件很长一段时间才完成,而有时即使移动的文件特别大时也能瞬间完成,原因在哪里呢?
这可能跟操作的`源文件`与`目标目录`是否在同一个文件系统下有关,
- 同一个文件系统下的移动文件或目录可以理解为位置或名称的变化,而数据不会移动。
- 不同文件系统下的移动文件或目录就需要先在目标文件系统的目录下新建文件,然后将数据复制到新文件中,最后删除源文件,所以会耗时长一些。
### 复制文件或目录命令-cp
`cp`命令用来复制文件。下面的命令将文件file1复制到文件file2:
```sh
$ cp file1 file2
```
下面的命令将多个文件(file1 ... fileN)复制到目录dir:
```sh
$ cp file1 ... fileN dir
```
### 文件格式信息参看命令-file
> linux系统的命令文件常常会不携带文件名后缀,那么我们如何识别文件格式呢?答案是使用`file`命令。
- 可以查看文件格式类型: 是文本文件、图片、视频或者二进制文件等等。
- 可以确定可执行程序是32位还是64位。
- 可以查看可执行程序是否可执行程序或者动态库是否剔除了符号信息(使用的函数等信息),可以通过分析使用的库函数来分析某些功能的实现逻辑。
我们可以通过`file`命令来查看文件格式信息:
```sh
$ file /usr/bin/ls
/usr/bin/ls: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=89963a71cfc1f2da28f8cbc218d92f8b624c808d, for GNU/Linux 3.2.0, stripped
$ file Linux_Installation_Instructions.pdf
Linux_Installation_Instructions.pdf: PDF document, version 1.3
$ file 2019-09-26-raspbian-buster-lite.zip
2019-09-26-raspbian-buster-lite.zip: Zip archive data, at least v2.0 to extract Zip archive data, at least v2.0 to extract
```
我们可以了解到`ls`命令是64位的`x86_64`架构可执行程序、pdf文档和zip压缩文件,知道了正确的文件格式才能够使用正确的解析方法。
### 修改文件的时间戳信息-touch
一个文件有三个时间戳信息:
- 最后访问时间(atime) : 最后读取文件内容的时间。
- 最后修改时间(mtime) : 最后写入文件内容的时间。
- 最后变更时间(ctime) : 最后修改文件属性信息的时间,例如`chmod`,`chown`。
```sh
# 新建文件或者更新已有文件的最后修改时间戳到当前系统时间
$ touch filename
# 自定义修改文件的时间戳信息(默认是最后修改时间戳,-a参数为最后访问时间)
# CC为年数中的前两位,YY为年数后两位,MM为月份,DD为天数,hh为小时数(24小时),mm为分钟,SS为秒数(0-61)
$ touch -t [[CC]YY]MMDDhhmm[.SS] filename
$ touch -a -t [[CC]YY]MMDDhhmm[.SS] filename
# -r reffile 可以将参考文件`reffile`的时间信息作为指定文件filename的新时间戳。
touch -r ref_file filename
```
### 实时查找文件命令-find
当我们想要查找某一个文件名的存放路径时就会使用`find`命令:
```sh
$ find ./ -name "config.xml" -type f
```
这是最简单的查找命令了,常见参数有:
- `-type` : 查找文件类型(f:文件, d:目录, p:命名管道,l:符号链接, s:套接字, b:块文件, c:字符文件)
- `-size` : 查找文件大小,可以携带 +/-符号表示大于/小于,单位可以有b:块(默认512字节),k:表示KB, M:表示MB, G:表示GB.
- `-name` : 查找的名字匹配规则
- `-mtime`: 查找文件的最后修改时间天数,例如+/-表示大于/小于, 0表示当前系统时间的24小时(86400秒)以内。
- `-newer`: 查找比参数设置的参考文件最后修改时间新的文件。
- `-exec` : 对查找的结果要执行的下一个命令,例如对查找文件执行删除操作, `find ./ -name "*.txt" -type f -exec rm -f {} \;`
- `-follow`: 不检索符号链接。
- `-depth`: 先处理目录的内容再处理目录本身。
对于一些复杂的条件可能还需要逻辑关系:
- `expr1 -a expr2` : expr1 并且 expr2
- `expr1 -o expr2` : expr1 或者 expr2
- `! expr` : expr条件的非运算
- `( expr )` : 括号表达式,解决符号或条件优先级问题,注意空格分割开。
### 根据索引查找文件命令-locate
`locate`命令是根据名称到文件索引库中匹配查找,特点是查找速度快,但是缺点是可能由于数据库更新频率满问无法实时查找到最新的文件位置。
### 文件路径的拆分命令-basename和dirname
例如一个文件路径`/tmp/config.conf`
- 获取存放的目录`/tmp`的命令: `dirname /tmp/config.conf`
- 获取文件名称`config.conf`的命令: `basename /tmp/config.conf`
### 修改文件的权限命令-chmod
### 修改文件的属主命令-chown
### 连接文件内容并输出的命令-cat
当我们想把两个文件内容按先后顺序合并输出时,可以使用`cat`命令:
```sh
cat file1 file2
```
### 查看文件的开始和末尾部分命令-head与tail
head命令显示文件的前10行内容(例如head /etc/passwd)。tail命令显示文件的最后10行内容(如tail /etc/passwd)。
你可以使用-n选项来设置显示的行数(例如:head -5 /etc/passwd)。如果要从第n行开始显示所有内容,使用tail +n。
### 统计文件磁盘占用大小的命令-du
```sh
$ du file
1024 file
# 递归统计当前目录下所有文件及目录占用磁盘情况(-h参数以人类可读格式展示,按文件大小显示单位K/M/G)
$ du -h ./*
# 只统计当前目录(不递归统计)的所有文件及目录磁盘使用情况
$ du -sh ./*
```
### 统计磁盘使用率情况的命令-df
> 为了防止磁盘空间被占满,我们会经常查看磁盘的使用情况,可以使用`df`命令
```sh
$ df -h /
文件系统 容量 已用 可用 已用% 挂载点
/dev/mapper/system-root 30G 24G 6.3G 79% /
```
### 分页查看文件的命令-more和less
> 有时我们只想查看或查找文件内容,并不想修改它,此时可以使用more或less命令。
`more`命令可以以分页方式查看文件内容,输入`/`加`keyword`查找关键词keyword所在位置。
`less`命令与`more`功能相似,差别在于`more`只能单向阅读,而`less`可以双向上、下阅读。
## 总结
以上命令都是非常基础的命令,也非常简单易用,学习的时候只需要在Linux系统中实际操作几次后就可以学会。如果想要更详细了解具体参数的信息,可以使用`man`命令查看命令的帮助文档。
---
~END~
- 前言
- 第一章 开始吧
- 1.0 选择适合你的Linux发行版
- 1.1 开始制作启动U盘
- 1.2 安装你的第一个Linux操作系统
- 1.3 安装Linux系统后要做的事情
- 1.4 什么是root用户
- 1.5 Linux下使用终端执行Shell命令
- 1.6 Linux软件安装方法介绍
- 1.7 Linux常用软件推荐
- *安装Manjaro发行版系统
- *安装Manjaro后要做的配置工作
- Flatpak安装软件方法
- 为什么Linux系统普及成都落后于Windows和MacOS?
- 第二章 Linux上的基础命令
- 2.0 环境变量及配置相关命令
- 2.1 文件及目录操作相关命令
- 2.2 文本处理相关命令
- 2.3 进程任务管理相关命令
- 2.4 用户管理相关命令
- 第三章 开发环境的部署
- 3.0 学习Shell编程
- 3.1 环境变量配置实例_如何配置JDK环境
- Python编程环境
- C语言编程环境
- 第四章 深入理解Linux系统
- 关于Linux不得不说的CopyLeft