文本编辑工具 vim vi 和 vim 简介
vi 是文本编辑器,vim 是 vi 的增强版。
一、vim 的常见模式和转换 1、三种常见模式
命令或普通模式 vim 打开一个文件的默认启动模式,可以实现光标移动、剪切/粘贴文本
插入或编辑模式 修改文本
扩展命令或命令(末)行模式 保存、退出等
2、模式之间的转换
命令模式 —> 插入模式
1 2 3 4 5 6 i insert,在光标所在处插入 I 在当前光标所在行的行首输入 a append,在光标所在处后面插入 A 在当前光标所在行的行尾输入 o 在光标所在行的下方插入一个新行 O 在当前光标所在行的上方打开一个新行
插入模式 —> 命令模式 Esc
命令模式 —> 末行模式 :
末行模式 —> 命令模式 Esc,Enter
示例:插入颜色字符
1 2 3 4 5 6 7 8 9 10 1、切换至插入模式 2、按ctrl+v+[ 三个键,显示^[ 3、后续输入颜色信息 4、切换至扩展命令模式,保存退出 5、cat 文件内容时看见相关颜色文本内容 [root@Rocky8-mini ~] ^[[1;31mHello^[[0m [root@Rocky8-mini ~]
二、末行模式 1 2 3 4 5 6 7 8 9 10 [root@Rocky8-mini ~] 1 root:$6$gwZKY4RbKMpHlO7S$FztMVac /skadP5/ALb.KQvjNRS4CvFcpiD8FfGPPMcbPahW/LfsEXHQXfz.f3eTVpMFvaDQCPLeX/dAPElpjK0::0:99999:7::: 2 bin:*:18700:0:99999:7::: 3 daemon:*:18700:0:99999:7::: ··· ··· 26 saslauth:!!:19078:::::: ~ :
2.1 末行模式基本命令 1 2 3 4 5 6 7 8 9 10 w 保存文件 wq 写入并退出 x 写入并退出 X 加密 q 退出 q! 强制退出 r filename 读入一个文件内容到当前文件的光标所在处 w filename 将当前文件内容写入另一个文件中 !command 在不退出vim的情况下,临时执行一个命令 r!command 读入一个命令的输出到当前文件中
2.2 地址定界 格式 :start_pos,end_pos CMD
2.2.1 地址定界格式 1 2 3 4 5 6 7 8 9 10 11 12 . 当前行 $ 最后一行 .,$-1 当前行到倒数第二行 % 全文 /PATTERN/ 从当前行向下查找,直到匹配查找到的字符串。支持正则表达式 /pat1/,/pat2/ 从第一个匹配到的模式开始到第二次匹配到的模式结束 /pat/,$ 从匹配到的第一个pat开始到文件末尾的所有行
2.2.2 地址定界后跟编辑命令 1 2 3 4 5 6 7 8 9 d 删除 y 复制 w file 将匹配到的行另存到指定文件中 r file 在指定位置插入指定文件的内容 :2,5d :5 r /etc/shadow
2.3 查找替换 2.3.1 查找 1 2 3 4 5 6 /PATTERN 从当前光标所在处向文件尾部查找; ?PATTERN 从当前光标所在处向文件首部查找; n:与命令同方向 N:与命令反方向 例: ?\<love\> 从当前光标处向文件首部查找love这个单词
2.3.2 查找并替换 1 2 3 4 5 6 7 8 9 10 11 12 13 s: 在末行模式下完成查找替换操作 s/要查找的内容/替换为的内容/修饰符 要查找的内容:可使用模式 替换为的内容:不能使用模式,但可以使用\1, \2, ...等后向引用符号;还可以使用“&”引用前面查找时查找到的整个内容; 修饰符: i: 忽略大小写 g: 全局替换;默认情况下,每一行只替换第一次出现; 查找替换中的分隔符/可替换为其它字符,否则就要用到转义符,例如 s@@@ s 例: :%s/\/etc\/fstab/\/var\/log/g 或 :%s@/var/log@/etc/fstab@g
2.4 定制 vim 工作特性 使用末行模式的配置只是对当前vim进程有效,可将配置存放在文件中永久保存。
配置文件:
1 2 /etc/vimrc 全局 ~/.vimrc 个人
2.4.1 行号 1 2 显示:set number, 简写为set nu 取消显示:set nonumber, 简写为set nonu
2.4.2 忽略字符大小写
2.4.3 自动缩进
2.4.4 复制保留模式 1 2 启用:set paste 禁用:set nopaste
2.4.5 显示Tab ^l 和换行符 $ 显示 1 2 启用:set list 禁用:set nolist
2.4.6 高亮搜索 1 2 启用:set hlsearch 禁用:set nohl
2.4.7 语法高亮 1 2 启用:syntax on 禁用:syntax off
2.4.8 文件格式 1 2 3 启用windows格式:set fileformat=dos 启用unix格式:set fileformat=unix 简写 set ff=dos|unix
2.4.9 Tab 用空格代替 1 2 启用:set expandtab(set et) 默认8个空格 禁用:set noet
2.4.10 Tab 用指定空格的个数代替
2.4.11 设置缩进宽度
2.4.12 设置文本宽度 1 2 set textwidth=65 (vim only) set wrapmargin=15
2.4.13 设置光标所在行的标识线
2.4.14 加密 1 2 启用:set key=PASSWORD 禁用:set key=
2.4.15 了解更多
三、命令模式 3.1 退出vim
3.2 光标跳转 3.2.1 字符间跳转
3.2.2 单词间跳转 1 2 3 4 w 下一个单词的词首 e 当前或下一个单词的词尾 b 当前或前一个单词的词首
3.2.3 当前页跳转 1 2 3 4 5 6 H 页首 M 页中间行 L 页底 zt 将光标所在当前行移到屏幕顶端 zz 将光标所在当前行移到屏幕中间 zb 将光标所在当前行移到屏幕底端
3.2.4 行首行尾跳转 1 2 3 ^ 跳转至行首的第一个非空白字符 0 跳转至行首 $ 跳转至行尾
3.2.5 行间移动
3.2.6 句间移动
3.2.7 段落间移动
3.2.8 命令模式翻屏操作 1 2 3 4 Ctrl+f 向文件尾部翻一屏,相当于Pagedown Ctrl+b 向文件首部翻一屏,相当于Pageup Ctrl+d 向文件尾部翻半屏 Ctrl+u 向文件首部翻半屏
3.3 字符编辑 1 2 3 4 5 x 剪切光标处的字符 xp 交换光标所在处的字符及其后面字符的位置 ~ 转换大小写 J 删除当前行后的换行符
3.4 替换命令 1 2 r 只替换光标所在处的一个字符 R 切换成REPLACE模式(末行有 -- REPLACE -- 提示),按Esc键回到命令模式
3.5 删除命令(实际为剪切) 1 2 3 4 5 6 7 8 9 10 d 删除,可通过光标跳转字符,实现范围删除 d$ 删除到行尾 d^ 删除到非空行首 d0 删除到行首 dw de db dd 删除光标所在的行D 从当前光标位置一直删除到行尾,等同于d$
3.6 复制命令 1 2 3 4 5 6 7 8 9 10 11 12 y 复制,行为相似于d命令 y$ y0 y^ ye yw yb yy:复制行 ------ 类似于d命令 ------
3.7 粘贴命令 1 2 p 缓冲区存的如果为整行,则粘贴当前光标所在行的下方;否则,则粘贴至当前光标所在处的后面 P 缓冲区存的如果为整行,则粘贴当前光标所在行的上方;否则,则粘贴至当前光标所在处的前面
3.8 改变命令 使用 c 命令后会进入到插入模式,用法类似于 d 命令
1 2 3 4 5 6 7 8 9 10 c$ c^ c0 cb ce cw cc C
3.9 撤销更改 1 2 3 4 5 6 u 撤销最近的更改,相当于windows中ctrl+z U 撤消光标落在这行后所有此行的更改 Ctrl-r 重做最后的“撤消”更改,相当于windows中crtl+y . 重复前一个操作
四、可视化模式 进入到可视化模式,末行有“– – VISUAL – –”指示
可视化模式的类型
v 面向字符 – VISUAL –
V 面向整行 – VISUAL LINE –
ctrl+v 面向块 – VISUAL BLOCK –
进入到可视化模式,被选中的文字可被删除,复制,变更,过滤,搜索,替换等
范例
1 2 3 4 5 6 7 1、在文件指定行的行首插入 - 先将光标移动到指定的第一行的行首 - 输入ctrl+v 进入到可视化模式 - 向下移动光标,选中希望操作的每一行的第一个字符 - 输入大写字母 I 切换至插入模式 - 输入 - 按 Esc 键
五、多文件模式 1 2 3 4 5 6 7 8 vim FILE1 FILE2 FILE3 ... :next 下一个 :prev 前一个 :first 第一个 :last 最后一个 :wall 保存所有 :qall 不保存退出所有 :wqall保存退出所有
六、多窗口模式 多文件模式
1 2 3 4 5 6 7 vim FILE1 FILE2 FILE3 ... :next 下一个 :prev 前一个 :first 第一个 :last 最后一个 :wall 保存所有 :qall 退出所有
窗口分割模式
1 2 3 4 5 6 7 8 9 10 vim -o|-O FILE1 FILE2 ... -o: 水平分割 -O: 垂直分割 在窗口间切换:Ctrl+w, Arrow 单文件窗口分割: Ctrl+w,s: split , 水平分割 Ctrl+w,v: vertical, 垂直分割 ctrl+w,q:取消相邻窗口 ctrl+w,o:取消全部窗口 :wqall 退出
文本常见处理工具 一、查看文件内容 1.1 查看文本文件内容 1.1.1 cat NAME cat - concatenate files and print on the standard output
1 2 3 4 5 6 [option] -E:显示行结束符$ -A:显示所有控制符 -n:对显示出的每一行进行编号 -b:只对非空行进行编号 -s:压缩连续的空行成一行
实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ------------ 支持标准输入 ----------- [root@Rocky8-mini ~] aaa ss dd gg [root@Rocky8-mini ~] aaa ss dd gg [root@Rocky8-mini ~] > line5 > EOF [root@Rocky8-mini ~] aaa ss dd gg line5
1.1.2 nl(相当于 cat -b) NAME nl - number lines of files
1 2 3 4 5 6 7 8 9 10 11 12 [root@Rocky8-mini ~] 1 1 2 2 3 3 4 5 5 [root@Rocky8-mini ~] 1 1 2 2 3 3 4 5
1.1.3 tac NAME tac - concatenate and print files in reverse
1 2 3 4 5 6 7 8 9 10 11 12 [root@Rocky8-mini ~] 5 4 3 2 1 [root@Rocky8-mini ~] 1 2 3 4 5
1.1.4 rev NAME rev - reverse lines characterwise
1 2 3 4 5 6 7 8 9 [root@Rocky8-mini ~] 01234 56789 [root@Rocky8-mini ~] 56789 01234 [root@Rocky8-mini ~] 43210 98765
1.2 查看非文本文件内容 1.2.1 hexdump 1 2 3 4 5 6 7 8 9 10 11 12 13 14 NAME hexdump - display file contents in hexadecimal, decimal, octal, or ascii SYNOPSIS hexdump [options] file... ------------------------------------------------------------ [root@Rocky8-mini ~] 00000000 eb 63 90 10 8e |.c...| 00000005 [root@Rocky8-mini ~] 00000000 61 20 62 20 63 20 64 20 65 20 66 0a |a b c d e f.| 0000000c [root@Rocky8-mini ~] 00000000 61 62 63 64 65 66 0a |abcdef.| 00000007
1.2.2 od 1 2 3 4 5 6 7 8 9 10 11 12 13 14 NAME od - dump files in octal and other formats -------------------------------------------------------------------- [root@Rocky8-mini ~] 0000000 64636261 68676665 6c6b6a69 706f6e6d 0000020 74737271 78777675 000a7a79 0000033 [root@Rocky8-mini ~] 0000000 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 0000020 71 72 73 74 75 76 77 78 79 7a 0a 0000033 [root@Rocky8-mini ~] 0000000 61 62 63 64 65 66 0a >abcdef.< 0000007
1.2.3 xxd 1 2 3 4 5 NAME xxd - make a hexdump or do the reverse. ------------------------------------------------------------------- [root@Rocky8-mini ~] 00000000: 6162 6364 6566 0a abcdef.
二、分页查看文件内容
1 2 3 more 和 less 都可实现文件的翻页 使用 more 查看文件到末尾时会自动退出,而 less 不会 less 查看文件时,支持使用模式匹配 /文本 搜索文本 n/N 跳到下一个 或 上一个匹配
三、显示文本前或后行内容 3.1 head 选项:
例:
1 2 3 4 5 6 7 8 9 [root@Rocky8-mini ~] 1 2 3 4 5 [root@Rocky8-mini ~] 1 2
3.2 tail 选项
1 2 3 4 -c -n -f 跟踪显示文件中的内容,当文件删除在新建一个同名文件时,无法继续跟踪 -F 也可跟踪显示文件中的内容,当文件删除又新建一个同名文件时可继续追踪
实例
1 2 3 4 5 6 7 8 9 [root@Rocky8-mini ~] 1 2 3 4 5 [root@Rocky8-mini ~] 4 5
四、按列抽取文本 cut 常用选项
1 2 3 4 5 6 7 8 -d DELIMITER:指明分隔符,默认为 Tab -f FILEDS: 混合使用: 1 -3 ,7 -c 按字符切割 --output-delimiter=STRING 指定输出分隔符
实例:
1 2 3 4 5 6 7 8 9 [root@Rocky8-mini ~] devtmpfs 897476 0 897476 0% /dev tmpfs 916616 0 916616 0% /dev/shm tmpfs 916616 8884 907732 1% /run tmpfs 916616 0 916616 0% /sys/fs/cgroup /dev/mapper/rl-root 31441920 1849564 29592356 6% / /dev/mapper/rl-data 17410832 45084 16458280 1% /data /dev/sda1 1038336 216624 821712 21% /boot tmpfs 183320 0 183320 0% /run/user/0
五、合并多个文件 paste 常用选项
1 2 -d DELIMITER: 指定分隔符,默认为 Tab -s 所有行合成一行显示
范例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [root@Rocky8-mini ~] 2 3 4 [root@Rocky8-mini ~] b c d [root@Rocky8-mini ~] 2 b 3 c 4 d [root@Rocky8-mini ~] 2 3 4 b c d
六、分析文本的工具 6.1 文本统计数据 wc 常用选项
1 2 3 4 -l 只计数行数 -w 只计数单词总数 -c 统计字节总数 -L 显示文件中最长行的长度
实例:
1 2 3 [root@Rocky8-mini ~] 27 46 1262 /etc/passwd 行数 单词数 字节数
6.2 文本排序 sort 常用选项
1 2 3 4 5 6 7 8 -r,--reverse reverse the result of comparisons -R 随机排序 -n 按照数字大小整理 -h 易读性排序,如 2M 1K -f 忽略字符大小写 -u 去重 -t 指定字段分隔符 -k
实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 ============== 统计分区的利用率 ============== [root@Rocky8-mini ~] /dev/sda1 21 % /dev/mapper/rl-root 7 % tmpfs 1 % /dev/mapper/rl-data 1 % tmpfs 0 % tmpfs 0 % tmpfs 0 % devtmpfs 0 % ============== 有两个文件,a.txt和b.txt,合并两个文件,并输出时确保每个数字唯一 ============= [root@Rocky8-mini ~] 2 3 4 [root@Rocky8-mini ~] 1 3 4 5 [root@Rocky8-mini ~] 1 2 3 4 5
6.3 文本去重 uniq 常用选项
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 -c 显示每行重复出现的次数 -d 仅显示重复过的行 -u 仅显示没有重复的行 [root@Rocky8-mini ~] 22 1 3 43 23 4 5 10 1 1 [root@Rocky8-mini ~] 1 [root@Rocky8-mini ~] 22 1 3 43 23 4 5 10
常与 sort 命令一起使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 -- 并发连接最多的远程主机 -- [root@Rocky8-mini ~] 4 192.168.119.1 2 192.168.119.158 1 192.168.119.147 -- 取两个文件的相同和不同的行 -- [root@Rocky8-mini ~] 2 3 4 [root@Rocky8-mini ~] 1 3 4 5 [root@Rocky8-mini ~] 3 4 [root@Rocky8-mini ~] 1 2 5
6.4 比较文件 6.4.1 diff -u 选项,使用 unified 格式显示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 [root@Rocky8-mini ~] root nginx wh wuhao harry [root@Rocky8-mini ~] mage root wuhao apache [root@Rocky8-mini ~] --- file1 2022-03-22 08:35:52.270539575 -0400 +++ file2 2022-03-22 08:38:20.195502598 -0400 @@ -1,5 +1,4 @@ +mage root -nginx -wh wuhao -harry +apache [root@Rocky8-mini ~] [root@Rocky8-mini ~] -- 先将 file1 文件备份成file1.org,然后根据f.patch文件和file1文件恢复原来的file2文件,但此时名称命名为file1 -- [root@Rocky8-mini ~] patching file file1 [root@Rocky8-mini ~] mage root wuhao apache [root@Rocky8-mini ~] root nginx wh wuhao harry
6.4.2 patch 略
6.4.3 vimdiff 略
6.4.4 cmp 略
练习 1、找出ifconfig “网卡名” 命令结果中本机的IPv4地址
1 2 [root@Rocky8-mini ~] 192.168.119.128
2、查出分区空间使用率的最大百分比值
1 2 [root@Rocky8-mini ~] 21%
3、查出用户UID最大值的用户名、UID及shell类型
1 2 [root@centos7-mini3 ~] wh:1000:/bin/bash
4、查出/tmp的权限,以数字方式显示
1 2 [root@centos7-mini3 ~] 1777
5、统计当前连接本机的每个远程主机IP的连接数,并按从大到小排序
1 2 3 4 [root@Rocky8-mini ~] 4 192.168.119.1 2 192.168.119.158 1 192.168.119.147
正则表达式 通配符通常用来匹配文件名,而正则表达式是用来匹配文本中的字符串。
正则表达式分类:
正则表达式的元字符分类:字符匹配、匹配次数、位置锚定、分组
注:grep命令的使用见文本处理三剑客文章
一、基本正则表达式元字符 1.1 字符匹配 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 . 匹配任意单个字符,可以使一个汉字 [] 匹配指定范围内的任意单个字符 [^] 匹配指定范围外的任意单个字符 [:alnum:] 字母和数字 [:alpha:] 任意大小写字母 [:lower:] 任意小写字母 [:upper:] 任意大写字母 [:blank:] 空白字符(空格和制表符) [:space:] 包括空格、制表符、换行符、回车符等各种类型的空白 [:cntrl:] 不能打印的控制字符(退格、删除、警铃···) [:digit:] 十进制数字 [:xdigit:] 十六进制数字 [:graph:] 可打印的非空白字符 [:print :] 可打印字符 [:punct:] 标点符号 \w \W \S \s Unicode 正则表达式会匹配全角空格符
1.2 匹配次数 用在要指定次数的字符后面,用于指定前面的字符要出现的次数
1 2 3 4 5 6 7 8 * 匹配前面的字符任意次,贪婪模式:尽可能长的匹配 .* 任意长度的任意字符 \? 匹配其前面的字符出现0 次或1 次 \+ 匹配其前面的字符至少出现1 次 \{n\} 匹配前面的字符n次 \{m,n\} 匹配前面的字符至少m次,最多n次 \{,n\} 匹配前面的字符最多n次 \{m,\} 匹配前面的字符至少m次
非捕获组标志 :
当问号与冒号一起使用,形如 (?:...)
时,它创建了一个非捕获组,其中的内容将被当作一个整体来匹配,但匹配结果不会被捕获到单独的组中。
1.3 位置锚定 位置锚定可以定位出现的位置
1 2 3 4 5 6 7 8 9 10 11 ^ 行首锚定,用于模式的最左侧 $ 行尾锚定,用于模式的最右侧 ^PATTERN$ 模式匹配整行 ^$ 匹配空行 ^[[:space:]] 空白行 \< 词首锚定 \> 词尾锚定 \<PATTERN\> 匹配整个单词 注:单词是由字母、数字、下划线组成,其他均为单词的分隔符 如:http_122、788hhh 为单词;http-122 、788 :hhh 为两个单词
实例
1 2 3 ----------- 排除掉空行和"#" 开头的行 ----------- [root@Rocky8-mini ~] [root@centos8 ~]
1.4 分组、或者 分组: ()将多个字符捆绑在一起,当作一个整体处理,如:\(root\)
后向引用: 分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名方式为:\1,\2,\3,…(\1 表示从左侧第一个左括号与之匹配的右括号之间的模式匹配到的内容)
Example:
1 2 3 4 \(ab\+\(xy\)*\): \1: ab\+\(xy\)* \2:xy 后向引用:引用前面的分组括号中的模式所匹配到的字符(也就是匹配到的结果),而非模式本身。
或者:\|
Example:
1 2 3 a\|b a或b c\|cat c或cat \(C\|c\)at Cat或cat
实例:
1 2 3 4 5 -------------------- 排除空行和'#' 开头的行 ---------------------- grep -v '^#' /PATH/TO/FILE |grep -v ^$ grep -v '^#\|^$' /PATH/TO/FILE grep -v '^\(#\|$\)' /PATH/TO/FILE grep "^[^#]" /PATH/TO/FILE
正则表达式练习 1、显示/proc/meminfo文件中以大小s开头的行(要求:使用两种方法)
1 2 [root@Rocky8-mini tmp] [root@Rocky8-mini tmp]
2、显示/etc/passwd文件中不以/bin/bash结尾的行
3、显示用户rpc默认的shell程序
4、找出/etc/passwd中的两位或三位数
5、显示CentOS7的/etc/grub2.cfg文件中,至少以一个空白字符开头的且后面有非空白字符的行
6、找出“netstat -tan”命令结果中以LISTEN后跟任意多个空白字符结尾的行
1 2 3 [root@Rocky8-mini ~] tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN tcp6 0 0 :::22 :::* LISTEN
7、显示CentOS8上所有UID小于1000以内的用户名和UID
8、添加用户bash、testbash、basher、sh、nologin(其shell为/sbin/nologin),找出/etc/passwd用户名和shell同名的行
9、利用df和grep,取出磁盘各分区利用率,并从大到小排序
1 2 3 4 [root@Rocky8-mini ~] /dev/sda1 21 /dev/mapper/rl-root 7 /dev/mapper/rl-data 1
二、扩展正则表达式元字符 扩展正则表达式元字符同基本正则表达式元字符,只是不需要加转义字符,词首锚定和词尾锚定仍然需要。
扩展正则表达式练习 1、显示三个用户root、mage、wang的UID和默认shell
1 2 3 4 [root@centos7 ~] 0:/bin/bash 1000:/bin/bash 1001:/bin/bash
2、找出/etc/rc.d/init.d/functions文件中行首为某单词(包括下划线)后面跟一个小括号的行
3、使用egrep取出/etc/rc.d/init.d/functions中其基名
1 2 3 4 [root@centos7 ~] functions [root@centos7 ~] functions
4、使用egrep取出上面路径的目录名
1 2 3 [root@centos7 ~] /etc/rc.d/init.d
5、统计last命令中以root登录的每个主机IP地址登录次数
6、利用扩展正则表达式分别表示0-9、10-99、100-199、200-249、250-255
1 2 3 4 5 grep -E "\<[0-9]\>" num.txt grep -E "\<[0-9]{2}\>" num.txt grep -E "\<1[0-9]{2}\>" num.txt grep -E "\<2[0-4][0-9]\>" num.txt grep -E "\<25[0-5]\>" num.txt
7、显示ifconfig命令结果中所有IPv4地址
8、将此字符串:welcome to wuhao linux 中的每个字符去重并排序,重复次数多的排到前面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 [root@Rocky8-mini ~] 3 o 2 w 2 u 2 l 2 e 1 x 1 t 1 n 1 m 1 i 1 h 1 c 1 a