第五章 使用文本文件
Linux 的大多数配置通过编辑纯文本文件完成。无论是修改 /etc 目录的文件配置本地服务,还是编辑 Ansible 目录文件配置主机的集合,纯文本文件仍然在这些任务中普遍使用
5.1 使用 vim 和 vi 编辑文件
vim 是 vi 的改良版本,两者使用差不多,但 vim 会有引导和代码高亮等,建议使用 vim
事实上,在部分 Linux 发行版中,vi 是使用别名 vim 来运行的,即输入 alias vi
输出为 alias vi = 'vim'
,但 root 用户一般不设置别名
不过在 Linux 还有其他文本编辑器,例如 nano、gedit、jed、joe、kate、kedit、mcedit、nedit 等,其中纯文本的有 jed 和 joe
5.1.1 开始使用 vi
vi 有三个模式,主要两种为 命令模式 和 输入模式 ,还有 ex 模式。默认进入文件为命令模式 (使用 vi file
命令进入后)
命令模式意味着在更改文本前需要先输入一条命令 (一俩个字母,有时还需要可选的数字参数) ,告诉 vi 您想做什么
注意:命令的大小写敏感
- 添加文本
如果要进入 输入模式 ,可以输入一个 输入 命令字母
命令 | 描述 |
---|---|
a | 添加命令。在光标右侧输入文本 |
A | 在命令结束处添加。从当前行末尾开始输入文本 |
i | 插入命令。在光标左侧输入文本 |
I | 在命令开始前插入。从当前行开头开始输入文本 |
o | 在命令之下打开。在当前行之下打开一个新行,并进入插入模式 |
O | 在命令之上打开。在当前行之上插入一个新行,并进入插入模式 |
进入插入模式后,在屏幕底部会出现 --INSERT--
完成文本输入后,按 Esc 键返回命令模式 (有时需要按两次 (反正按 Esc 就对了)
- 在文本中移动
仅移动一个字符使用以下按键
按键 | 描述 |
---|---|
箭头键 | 上下左右 |
h, j, k, l | 左,下,上,右 |
Backspace, Space | 左,右 |
移动多个字符的命令
命令 | 描述 |
---|---|
w | 将光标移动到下一个单词的开头 (用空格、制表符或标点符号分隔) |
W | 将光标移动到下一个单词的开头 (用空格或制表符分隔) |
b | 将光标移动到前一个单词的开头 (用空格、制表符或标点符号分隔) |
B | 将光标移动到前一个单词的开头 (用空格或制表符分隔) |
0 (零) | 将光标移到当前行的开头 |
$ | 将光标移到当前行的末尾 |
H | 将光标移到屏幕左上角 (屏幕上第一行) |
M | 将光标移到屏幕中间行的第一个字符 |
L | 将光标移到屏幕的左下角 (屏幕上的最后一行) |
- 删除、复制和更改文本
这些命令可以配合移动键 (箭头、PgUp、PgDn、字母和特殊键) 和数字来确切指出删除、复制或更改什么
命令 | 描述 |
---|---|
x | 删除光标下的字符 |
X | 直接删除光标之前的字符 |
d | 删除一些文本 |
c | 更改一些文本 |
y | 复制一些文本 |
上表每个命令后的 <?>
代表了可使用移到命令的位置,例如
- dw — 删除当前光标之后的一个单词
- db — 删除当前光标之前的一个单词
- dd — 删除整个当前行
- c$ — 更改当前字符开始到当前行末尾的字符并进入输入模式 (事实上就是删除后输入)
- c0 — 更改从前一字符开始到当前行开头的字符并进入输入模式 (事实上就是删除后输入)
- cl — 删除当前字符并进入输入模式
- cc — 删除当前行并进入输入模式
- yy — 将当前行复制到缓冲区
- y) — 将光标右边的句子复制到缓冲区
- y} — 将光标右边的段落复制到缓冲区
也可以使用数字对上述命令进行修改,例如
- 3dd — 从当前行开始,删除 3 行
- 3dw — 删除接下来的 3 个 单词
- 5cl — 更改接下来 5 个字符 (也就是删除后进入输入模式)
- 12j — 向下移动 12 行
- 5cw — 删除接下来 5 个单词并进入输入模式
- 4y) — 复制接下来的 4 个句子
- 粘贴 (放置) 文本
将最新存储到缓冲区的文本放到文件中
命令 | 描述 |
---|---|
P | 放到光标左边,若为一行,放到上一行 |
p | 放到光标右边,若为一行,放到下一行 |
- 重复命令
在删除、更改或粘贴文本后,通过 .
以重复行为。例如替换文本 Joe 为 Jim (cw) 后查找下一处按 .
以重复更改
- 推出 vi
在命令模式下直接使用 ZZ
保存后退出,也可按 :
进入 ex 模式
命令 | 描述 |
---|---|
:w | 保存当前文件,不退出 |
:wq | 保存并退出,与 ZZ 相同 |
:q | 退出,但仅未更改生效 |
:q! | 强制退出,不保存更改 |
- 其他命令
- u — 撤销更改
- Ctrl+R — 恢复撤销 (重做) ,也就是撤销了先前的撤销操作
- :!command — 在
:!
后跟一个 shell 命令,可直接运行,例如:!date
查看当前日期。设置可以通过:!bash
以启动一个新 shell,但建议进入前先保存,以防忘记返回 vi - Ctrl+g — 显示正在编辑的文件名,底部还有当前所在行、文件总行数、内容百分比以及光标所在列号
5.1.2 在文件中跳过
如果文件较长,用此方法移动更好
命令 | 描述 |
---|---|
Ctrl+f | 向前翻页,一次一页 |
Ctrl+b | 向后翻页,一次一页 |
Ctrl+d | 向前翻半页 |
Ctrl+u | 向后翻半页 |
G | 转到文件最后一行 |
nG | 转到文件第 n 行 (用数字替换 n) |
5.1.3 搜索文本
通过 /
与 ?
向前或向后搜索文本,还可以使用元字符,例如
- /hello* — 向前搜索 hello 开头的行
- ?[pP]rint — 向后搜索单词 print 或 Print
在输入搜索后通过 n
或 N
可以在相同或相反方向载体搜索
5.1.4 使用 ex 模式
vi 编辑器最初基于 ex 编辑器,因此无法在全屏模式下工作,但可以在 ex 模式下使用命令找到并更改一行或多行的文本,例如
在命令模式下使用 :
进入 ex 模式
- :g/Local — 搜索单词 Local,并打印相关行,如果输出结果满屏将发送到 more 命令
- :s/Local/Remote — 将当前行首次出现的单词 Local 替换为 Remote
- :g/Local/s//Remote — 文件每一行首次 Local 替换为 Remote
- :g/Local/s//Remote/g — 文件所有 Local 替换为 Remote
- :g/Local/s//Remote/gp — 文件所有 Local 替换为 Remote,并打印每一行
5.1.5 了解更多
使用 vimtutor
将在 vim 编辑器中打开一个教程
5.2 查找文件
为帮助找到系统中的文件,可使用一些命令
- locate — 根据名称查找文件
- find — 根据不同的属性查找文件
- grep — 在文本文件内部搜索包含所搜索文本的行
5.2.1 使用 locate 命令根据名称查找文件
大多数 Linux 系统每天会运行一次 updatedb 命令,收集 Linux 系统中文件名并存入数据库,使用 locate 命令可从该数据库中搜索文件位置。可通过 sudo updatedb
命令更新数据库。仅可通过 locate 命令查看允许用户访问的文件
locate [str]
,或者使用 locate -i [str]
以忽略大小写。例如搜索包含 yexca 的目录并忽视 yexca 的大小写:locate -i yexca
注:并不是所有的文件都在数据库,/etc/updated.conf
文件内容限制了被收集的文件
5.2.2 使用 find 命令搜索文件
find 命令是在文件系统中搜索文件的最佳命令,可以基于不同属性 (元数据) 查找,并且可以在找到文件后进行处理
注:文件元数据包括所有者、组、时间戳、文件大小、权限以及存储在文件 inode 中的其他信息
find 与 locate 的区别
使用 find 查找将搜索文件系统,所以速度会比 locate 慢许多,不过可以实时查看系统中文件 (对于 locate 命令,如果文件过新未收录到数据库将无法被找到)。当然,使用 find 时要设置搜索起始点以限制搜索范围从而提高速度
find 命运有一个特殊的选项 -ls
,可以列出搜索到文件的详细信息,类似 ls -l
命令的输出
注:对于普通用户搜索文件因权限问题会有许多错误,可将错误输出定向到 /dev/null 以忽略,即在命令末尾添加 2>/dev/null
- 根据文件名查找文件
使用 -name
和 -iname
(忽略大小写) 以输入想要搜索的文件名,也可使用文件匹配字符 (* 和 ?),例如
find /etc -iname '*passwd*'
在 /etc 目录下搜索包含 passwd 单词并忽略大小写的文件 (如不指定目录 (/etc) 将搜索当前文件夹)
可使用 -type
选项以指定输出仅文件 (-type f
) 或仅目录 (-type d
)
- 根据文件大小查找文件
通过 -size
选项和以 +
或 -
开头的数字查找相应范围,例如 find /etc -size +10M
查找 /etc 目录下大于 10MB 的文件
find /bigdata -size +500M -size -5G -exec du -sh {} \
查找 /bigdata 目录下 500MB ~ 5GB 之间的文化,并针对每个文件运行 du 命令以查看文件大小
- 根据用户查找文件
通过 -user
或 -group
以针对特定用户或组查找,还可使用 -not
和 -or
find /home \( -user yexca -or -user lemon \) -ls
查找 /home 目录下 yexca 和 lemon 所拥有的文件
- 根据权限查找文件
使用 -perm
选项,根据数字或字母找到文件。如果数字前使用 -
,则三位都要匹配;如果使用 +
,任一数字匹配即可;若不加东西,那么所有数字必须完整、精确匹配 (因用户不同)
如果 find -perm /002
则将找到对 “其他人” 启用了写入权限的文件,而不用管其他权限位如何设置
- 根据日期和时间查找文件
time 选项 (-atime、-ctime 和 -mtime) 能基于自文件被访问、更改或者文件的元数据被更改以来所经历的天数进行搜索。而 min 选项 (-amin、-cmin 和 -mmin) 则是基于所经历的分钟数进行修改
在上述俩选项的参数前加 -
表示从当前时间到所查询的时间单位前的时间,+
表示所查询时间单位之前以及更久的时间,如果省略,则完全匹配
- 查看 10 分钟内被更改的内容 find /etc -mmin -10
- 查看三天内权限更改 find /bin /usr/bin -ctime -3
- 查看 300 多天未被访问的文件 find /var/www -atime +300
- 在查找文件时使用 ‘not’ 和 ‘or’
通过使用 -not
或 -or
选项可以更好地搜索
- 查找被 yexca 所有但不属于 yexca 组的文件 find /home -user yexca -not -group yexca -ls
- 被 yexca 所有并且大于 1GB 的文件 find /home -user yexca -and -size +1G -ls
- 查找文件和执行命令
通过使用 -exec
选项,可以在每一个找到的文件执行命令而不必确认,或使用 -ok
以确认是否执行该命令。两者语法相同
find [options] -exec command {} \;
find [options] -ok command {} \;
其中 {}
表示被找到的文件名,可多次使用。在命令末尾需要使用 \;
。例如
find /etc -iname passwd -exec echo "I found {}" \;
查找名为 passwd 的文件并在 echo 的输出中包含该名称
注:若了解更多,使用 man find
命令
5.2.3 使用 grep 命令在文件中搜索
使用 grep 命令可以搜索包含某一文本 (搜索内容) 的文件。当搜索时,可以把包含文本的所有行打印,或只打印相关文件。grep 还可以搜索标准输出
选项 | 描述 |
---|---|
-i | 忽略大小写 |
-v | 搜索不包含指定文本的行 |
-r | 递归搜索某目录的文件 |
-l | 仅显示文件 |
–color | 突出显示搜索文本 (默认为红色) |
- 在 /etc/sysconfig 目录递归搜索文本 root grep -ri –color root /etc/sysconfig/
- 从标准输出中搜索包含 inet 的行 ip addr show | grep inet