1. 文本編輯工具vim
1.1 vim介紹
在Linux中我們經(jīng)常編輯修改文本文件, 即由ASCII, Unicode或其他編碼的純文字的文件. Vim是一款使用最多的Linux平臺(tái)的文本編輯工具
vim安裝:
# 最小化安裝的系統(tǒng), 需要單獨(dú)安裝vim包
[root@demo-c8 ~]# rpm -ql vim-enhanced
/etc/profile.d/vim.csh
/etc/profile.d/vim.sh
/usr/bin/rvim
/usr/bin/vim
/usr/bin/vimdiff
/usr/bin/vimtutor
/usr/lib/.build-id
/usr/lib/.build-id/7f
/usr/lib/.build-id/7f/37d6ce6c2273cc7bdf383618236c268dbeb092
1.2 使用 vim 初步
1.2.1 vim 命令格式
vim [OPTION]... FILE...
常用選項(xiàng):
vim打開文件, 光標(biāo)默認(rèn)處在第一行行首
+# 打開文件后,讓光標(biāo)處于第#行的行首,`vim + FILE`: 打開文件后, 光標(biāo)處于最后一行行首.
+/PATTERN 讓光標(biāo)處于第一個(gè)被PATTERN匹配到的行的行首
-b file 二進(jìn)制方式打開文件
-d file1 file2... 比較多個(gè)文件,相當(dāng)于 vimdiff
-m file 只讀打開文件
-e file 直接進(jìn)入ex模式,相當(dāng)于執(zhí)行ex file
-y file Easy mode (like "evim", modeless),直接可以操作文件,ctrl+o:wq|q! 保存和不保存退出
說明:
- 如果該文件存在,文件被打開并顯示內(nèi)容
- 如果該文件不存在,當(dāng)編輯后第一次存盤時(shí)創(chuàng)建它
1.2.2 三種主要模式和轉(zhuǎn)換
vim 是一個(gè)模式編輯器,其行為是依賴于 vim的模式
三種常見模式:
- 命令或普通(Normal)模式:默認(rèn)模式,可以實(shí)現(xiàn)移動(dòng)光標(biāo),剪切/粘貼文本
- 插入(Insert)或編輯模式:用于修改文本
- 擴(kuò)展命令(extended command )或命令(末)行模式:保存,退出等
模式轉(zhuǎn)換
- 命令模式 --> 插入模式
i insert, 在光標(biāo)所在處輸入
I 在當(dāng)前光標(biāo)所在行的行首輸入
a 在當(dāng)前光標(biāo)所在處后面輸入
A 在當(dāng)前光標(biāo)所在行行尾輸入
o 在當(dāng)前光標(biāo)所在行的下方打開一個(gè)新行
O 在當(dāng)前光標(biāo)所在行的上方打開一個(gè)新行
行首插入: I
行尾插入: A
上一行插入: O
下一行插入: o
光標(biāo)處插入: i
光標(biāo)處下一位插入: a
- 插入模式 --
ESC-- 命令模式 - 命令模式 --
:-- 擴(kuò)展命令模式 - 擴(kuò)展命令模式 --
ESC-- 命令模式
1.3 擴(kuò)展命令模式
按冒號(hào) " : " 可以進(jìn)入Ex模式,創(chuàng)建一個(gè)命令提示符: 處于底部的屏幕左側(cè)
1.3.1 擴(kuò)展命令模式基本命令
w 寫(存)磁盤文件
wq 寫入并退出
x 寫入并退出
X 加密
q 退出
q! 不存盤退出,未保存更改都將丟失
r filename 讀取文件內(nèi)容到當(dāng)前文件中, 在光標(biāo)所在行下一行插入
范例: :r/data/prac/test.txt, 如果讀取的是和當(dāng)前文件在同一個(gè)目錄的文件, 要使用./文件名
w filename 將當(dāng)前文件內(nèi)容寫入另一個(gè)文件
范例: :w/data/prac/test.txt, 如果寫入的是和當(dāng)前文件在同一個(gè)目錄的文件, 要使用./文件名. 如果目標(biāo)文件不存在, 會(huì)自動(dòng)創(chuàng)建文件, 并寫入內(nèi)容
如果目標(biāo)文件存在, 那么就要加!,去覆蓋掉原文件內(nèi)容, :w!./f1.txt
!command 執(zhí)行命令, 打印在屏幕上,但是不會(huì)追加到文件中
r!command 讀取命令的輸出. 將命令的輸出追加到鼠標(biāo)當(dāng)前行的下一行
1.3.2 地址定界
在末行模式執(zhí)行
格式:
地址界定后需要接命令, 來完成操作
:start_pos,end_pos CMD
1.3.2.1 地址定界格式
在末行模式輸入以下格式
1. # 將光標(biāo)移動(dòng)到第幾行的行首, :2就是移動(dòng)到第二行行首
2. . 將光標(biāo)移動(dòng)到當(dāng)前行的行首
3. $ 將光標(biāo)移動(dòng)到最后一行行首, %也是移動(dòng)到最后一行行首
4. $-# 將光標(biāo)移動(dòng)到倒數(shù)第#+1行, $-1就是倒數(shù)第二行; 因?yàn)榈箶?shù)第一行是$, $-1就是倒數(shù)第二行
5. #,# 選定范圍,從第#起, 到第#行止; 2,5就是第二行到第五行;配合后續(xù)命令使用,
比如, 刪除從第2行到第5行的數(shù)據(jù)就是, :2,5d
:10,20y,就是復(fù)制從第10行到第20行數(shù)據(jù)
復(fù)制后可以移動(dòng)光標(biāo)到某一行,然后輸入p鍵, 則把復(fù)制內(nèi)容粘貼到該行的下一行.
即使粘貼時(shí), 光標(biāo)不在行首也沒關(guān)系, 因?yàn)闀?huì)復(fù)制到下一行,而不是從光標(biāo)當(dāng)前位置開始插入
6. #,+# 從第#行開始起, 向下取#行, 2,+3 就是從第二行開始向下取3行, 也就是第2到5行
7. .,$-1 從當(dāng)前行到倒數(shù)第二行; .,$-#, 從當(dāng)前行到倒數(shù)第#+1行
8. % 表示全文, 相當(dāng)于 1,$
1.3.2.2 地址定界后跟一個(gè)編輯命令
d #刪除, 相當(dāng)于剪切
y #復(fù)制
w file #將范圍內(nèi)的行另存至指定文件中 1,2w /opt/passwd.txt
r file #在指定行的下一行插入指定文件中的所有內(nèi)容 1r /opt/passwd.txt
1.3.3 查找并替換
格式:
搜索范圍s/要查找的內(nèi)容/替換為的內(nèi)容/修飾符
說明:
要查找的內(nèi)容: 可使用基本正則表達(dá)式模式
替換為的內(nèi)容: 不能使用模式, 但可以使用\1, \2, ...等后向引用符號(hào); 還可以使用"&"引用前面查找時(shí)查找到的整個(gè)內(nèi)容
范例: 搜索/etc/password中的root賬號(hào), 替換為admin
- 不加修飾符, 默認(rèn)情況會(huì)查找范圍內(nèi)全部匹配到的數(shù)據(jù), 但是每一行只會(huì)替換第一個(gè)匹配到的字符
:%s/root/admin/ # %為全文搜索
- 通過修飾符g, 替換范圍內(nèi)全部匹配到的數(shù)據(jù)
:%s/root/admin/g
- 通過修飾符i, 定義搜索時(shí)不區(qū)分大小寫, 默認(rèn)搜索是區(qū)分大小的.
:%s/admin/ROOT/ig
注意: 搜索是可以區(qū)分或者不區(qū)分大小寫, 但是替換的內(nèi)容一定是區(qū)分大小的, 替換成ADMIN就是改成ADMIN
查找替換中的分隔符/可以替換為其他字符, @,#
范例:
s@@@
s###
1.3.4 定制vim的工作特性
擴(kuò)展命令模式的配置只是對(duì)當(dāng)前vim進(jìn)程有效, 可將配置存放在文件中持久保存
配置文件:
/etc/vimrc 全局
~/.vimrc 個(gè)人
針對(duì)vim正在打開的文件臨時(shí)生效:
范例: 用4個(gè)空格表示tab
切換到末行模式, 針對(duì)某個(gè)腳本設(shè)置
:set expandtab
:set 4
注意: 一旦關(guān)閉文件后, 臨時(shí)的配置就會(huì)失效, 下次打開文件后, 需要再次設(shè)置
9. :set nu 顯示行號(hào)
10. :set nonu 不顯示行號(hào)
11. :set nohl 不高亮
12. 命令(普通)模式直接輸入/, 進(jìn)入搜索模式, 可以搜索關(guān)鍵字
1.3.4.1 行號(hào)
顯示行號(hào): set no
取消顯示: set nonu
1.3.4.2 忽略字符的大小寫
啟用: set ic
不忽略: set noic
1.3.4.3 自動(dòng)縮進(jìn)
啟用: set ai, 輸入回車后, 下一行和上一行行首對(duì)齊
禁用: set noai
1.3.4.4 復(fù)制保留格式
啟用: set paste, 使用了set ai后, 防止粘貼文本時(shí)串行, 出現(xiàn)格式混亂
禁用: set nopaste
1.3.4.5 顯示Tab^|和換行符$
啟用: set list
禁用: set nolist
1.3.4.6 高亮搜索
啟用: set hls
禁用: set nohl
1.3.4.7 語法高亮
啟用: syn on
禁用: syn off
1.3.4.8 文件格式
啟用Windows格式: set fileformat=dos
啟用Unix格式; set fileformat=unix
簡(jiǎn)寫 set ff=dos|unix, 將文本格式改為Windows/Unix
1.3.4.9 Tab用空格代替
不同的遠(yuǎn)程工具下, tab和空格數(shù)量的對(duì)應(yīng)關(guān)系不同
啟用: set expandtab 默認(rèn)為8個(gè)空格代替Tab
禁用: set noexpandtab
1.3.4.10 Tab用指定空格的個(gè)數(shù)代替
啟用: set tabstop=# 指定#個(gè)空格代替Tab
簡(jiǎn)寫: set ts=4
1.3.4.11 設(shè)置光標(biāo)所在行的標(biāo)識(shí)線
啟用: set cul
禁用: set nocursorline
1.3.4.12 幫助
set 幫助
:help option-list
:set or :set all
1.4 命令模式(普通模式)
行首行尾跳轉(zhuǎn)
^: 跳轉(zhuǎn)至行首的第一個(gè)非空白字符
0: 跳轉(zhuǎn)至行首
$: 跳轉(zhuǎn)至行尾
行間移動(dòng)
# 擴(kuò)展命令模式下: :行編號(hào), :1表示第一行 :%最后一行
# 普通命令模式下: 行編號(hào)G, 1G或者gg表示第一行, G表示最后一行
替換命令
r: 只替換光標(biāo)所在處的一個(gè)字符
R: 切換到REPLACE模式, 在末行會(huì)出現(xiàn)REPLACE提示, 按ESC回到命令模式
刪除命令
d: 刪除命令, 可結(jié)合光標(biāo)跳轉(zhuǎn)字符, 實(shí)現(xiàn)范圍刪除
d$: 刪除光標(biāo)當(dāng)前到行尾, 或者用D
d^: 刪除光標(biāo)當(dāng)前到非空行首
d0: 刪除光標(biāo)當(dāng)前到行首
dd: 剪切光標(biāo)所在行, 之后可以移動(dòng)到目標(biāo)處用p粘貼到光標(biāo)下一行
數(shù)字dd: 刪除從當(dāng)前行開始的多行, 2dd表示從當(dāng)前行開始, 刪除兩行, 包括當(dāng)前行
dG: 從光標(biāo)所在行開始往后, 刪除整個(gè)文本
dgg: 從光標(biāo)所在行開始往前, 刪除整個(gè)文件
刪除當(dāng)前行尾的換行符
# 也就是把下面一行和當(dāng)前行合并, 將光標(biāo)移動(dòng)到上面一行, 然后敲J
J
大小寫轉(zhuǎn)換
~
復(fù)制和粘貼
y: 復(fù)制
yy: 復(fù)制當(dāng)前行, 相當(dāng)于Y
y$: 從光標(biāo)處復(fù)制到行尾
y0: 從光標(biāo)處復(fù)制到行首
y^: 從光標(biāo)處復(fù)制到非空行首
數(shù)字yy: 從當(dāng)前行開始復(fù)制多行
P: 將復(fù)制的內(nèi)容粘貼到光標(biāo)所在行的上面
p: 將復(fù)制的內(nèi)容粘貼到光標(biāo)所在行的下面
查找
/模式: 從當(dāng)前光標(biāo)所在處向文本末尾查找
?模式: 從當(dāng)前光標(biāo)所在處向文本首部查找
n: 與命令同方向
N: 與命令反方向
撤銷
u: 撤銷最近的更改
數(shù)字u: 撤銷之前幾次更改
U: 撤銷光標(biāo)所在行此行的所有更改
ctrl+r: 重做最后一次撤銷的更改
高級(jí)用法
- <起始位置><命令><結(jié)束為止>
常見命令: y復(fù)制, d刪除, gU變大寫, gu變小寫
范例: 復(fù)制一行內(nèi)容
0y$
0: 先定位到行首
y: 從行首開始賦值
$: 拷貝到本行的最后一個(gè)字符
范例: 粘貼"admin"100次
100iadmin[ESC]
命令模式執(zhí)行
敲100, 表示粘貼100次
敲i, 進(jìn)入插入模式
敲admin, 輸入要粘貼的內(nèi)容
敲ESC退出插入模式, 回到普通模式
- 針對(duì)一組特殊符號(hào)內(nèi)的內(nèi)容進(jìn)行操作
范例: 刪除一組特殊符號(hào)內(nèi)的內(nèi)容
di[
命令模式執(zhí)行, 并且要將光標(biāo)先移動(dòng)到這組特殊符合內(nèi)
d: 執(zhí)行刪除
i:
[: 表示刪除的是一組[]內(nèi)的全部?jī)?nèi)容
yi(
di"
di'
dtx: 從當(dāng)前光標(biāo)位開始刪除, 直到遇到第一個(gè)字符x
ytx: 從當(dāng)前光標(biāo)位開始復(fù)制, 直到遇到第一個(gè)字符x
1.5 可視化模式
- 通過鍵盤光標(biāo)選中要修改的字符/行或者矩形塊, 然后進(jìn)行內(nèi)容操作
v: 面向字符, 在末行顯示 -- VISUAL --, 可以按照字符進(jìn)行選擇, 然后執(zhí)行命令, 比如刪除或者復(fù)制
V: 面向整行, 在末行顯示 -- VISUAL LINE --, 按照一整行去選擇, 然后執(zhí)行命令, 比如刪除或者復(fù)制
ctrl+v: 面向塊, 按照一個(gè)矩形塊去選擇, 在末行顯示 -- VISUAL BLOCK --
范例: 在指定的列插入相同的內(nèi)容
1. 將光標(biāo)移動(dòng)到要操作的行
2. ctrl+v, 進(jìn)入可視化模式, 選擇要操作的列和行
3. 輸入I
4. 輸入要插入的內(nèi)容
5. 按ESC鍵
案例1: 在整個(gè)文件的行首, 插入#
gg, 先將光標(biāo)移動(dòng)到文件首行
ctrl+v, 進(jìn)入塊可視化模式
輸入G, 這樣可以選中每一行的第一個(gè)字符
輸入I, 切換至插入模式, 這樣可以在每一行的行首插入字符
輸入#
ESC退出可視化模式
案例2: 刪除每一行的第一個(gè)字符
gg, 先將光標(biāo)移動(dòng)到文件首行
ctrl+v
G
x
ESC
案例3: 在指定的列插入相同的內(nèi)容
原理和插入#一樣
ctrl+v
移動(dòng)光標(biāo)選中需要插入信息的列
輸入I
輸入內(nèi)容
ESC
案例4: 復(fù)制/etc/rc.d/init.d/functions文件至/tmp目錄. 替換/tmp/functions文件中的/etc/sysconfig/init為/var/log
:%s#/etc/sysconfig/init#/var/log#
案例5: 刪除/tmp/functions文件中所有以#開頭, 且#后面至少有一個(gè)空白字符的行的行首的#號(hào)
:%s@^#\( \+.*\)@\1@ # vim末行模式的搜索替換只支持基本正則表達(dá)式
2 文本常見處理工具
2.1 文本內(nèi)容查看命令
2.1.1 查看文本文本內(nèi)容
2.1.1.1 cat
cat 只能看文本文件, cat文件之前, 可以先通過file命令查看文本格式, 確定是否可以cat查看
[root@demo-c8 ~]# file /dev/urandom
/dev/urandom: character special (1/9)
[root@demo-c8 ~]# file /etc/fstab
/etc/fstab: ASCII text
格式:
cat [OPTION]... [FILE]...
常見選項(xiàng):
-E 顯示行結(jié)束符$
-A 顯示所有控制符
-n 對(duì)顯示出的每一行進(jìn)行編號(hào)
-b 僅對(duì)非空行顯示行號(hào), 等于`nl`命令
-s 壓縮連續(xù)的空行成一行
范例: cat -A查看Linux格式文件
# 準(zhǔn)備測(cè)試文件
[root@demo-c8 ~]# cd /data
[root@demo-c8 data]# ls
[root@demo-c8 data]# vim f1.txt
a b
cc
d i v
-
cat -A: $:Linux的換行符
image.png
[root@demo-c8 data]# hexdump -C f1.txt # $符號(hào)就是0a換行
00000000 61 20 20 20 62 0a 63 63 0a 64 20 69 20 76 20 0a |a b.cc.d i v .|
00000010
范例: cat -A查看Windows格式文件

- cat -A: . ^M: Windows格式的回車符號(hào), 也就是0d

[root@demo-c8 data]# hexdump -C a.txt
00000000 61 20 20 31 0d 0a 62 20 20 32 0d 0a 63 20 20 33 |a 1..b 2..c 3|
00000010
范例: cat多行重定向生成配置文件
cat > FILE_NAME <<EOF
>
>
EOF
- reset命令
恢復(fù)終端環(huán)境, 比如用cat打開了一些非文本文件后, 可能會(huì)執(zhí)行一些亂碼. 這時(shí)可能出現(xiàn)cat其他文本文件也是亂碼的情況, 這時(shí)用reset命令恢復(fù)終端環(huán)境. 如果還不行, 可以斷開SSH連接, 或者重啟. 重啟再不行,就排錯(cuò)吧. 所以不要用cat命令隨便打開文件.
- tac命令
反向顯示文本內(nèi)容, 把第一行顯示在最后一行, 和cat正好相反
- rev命令
反向顯示文本內(nèi)容, 把第一列顯示在最后一列, 和cat正好相反
2.1.2 查看非文本文件內(nèi)容
2.1.2.1 hexdump
- hexdump命令
有些文件是非文本文件, 可以用hexdump查看, 并且以指定的進(jìn)制顯示
格式:
hexdump [options] <file>...
Display file contents in hexadecimal, decimal, octal, or ascii.
一般用-C選項(xiàng)以16進(jìn)制顯示, 比如hexdump -C -n 512 /dev/sda, 查看sda硬盤前512字節(jié)
硬盤的前512個(gè)字節(jié)是非文本內(nèi)容

范例: 將文本字符以ASCII碼16進(jìn)制顯示
[root@demo-c8 ~]# echo abcd | hexdump -C
00000000 61 62 63 64 0a |abcd.|
00000005
2.2 分頁查看文件內(nèi)容
只要是支持標(biāo)準(zhǔn)輸入的命令都可以用管道, 將前面命令的結(jié)果傳給自己
more FILE
回車, 下一行
空格, 下一頁
ctrl+d: 往回翻
q: 退出查看
缺點(diǎn): 翻到了最后一頁就自動(dòng)退出, 不能再往回翻
less FILE
q: 退出查看
支持page up | page down翻頁
翻到了最后一頁不會(huì)自動(dòng)退出
輸入/可以搜索, n跳到下一個(gè)匹配, N跳到上一個(gè)匹配, 和vim中的搜索用法相同
2.3 顯示文本前或后n行內(nèi)容
head命令
默認(rèn)顯示文本前10行
-n數(shù)字 或者 -數(shù)字: 顯示文本的前幾行
-C數(shù)字: 顯示文本的前幾個(gè)字節(jié)
范例: head顯示前n行
[root@demo-c8 ~]# seq 100 > text.txt
[root@demo-c8 ~]# head text.txt
1
2
3
4
5
6
7
8
9
10
范例: head顯示前n個(gè)字節(jié)
# 數(shù)字和換行符各占一個(gè)字節(jié)
[root@demo-c8 ~]# head -c 10 text.txt
1 # 1和換行符
2
3
4
5
tr命令
-d 刪除指定內(nèi)容
-s 壓縮, 將連續(xù)的指定內(nèi)容壓縮成一個(gè)字符
-c 取反, -dc就是除了后面匹配的內(nèi)容, 都刪除, 可以接通配符
面試題: 生成字符+數(shù)字隨機(jī)密碼
利用/dev/urandom文件, 該文件是字符塊文件,生成隨機(jī)信息, 不能用cat直接查看顯示在屏幕上, 但是可以將cat結(jié)果通過管道傳給tr命令, 然后把除了字符和數(shù)字的其他字符亂碼都刪除.這樣就保留了隨機(jī)的字符和數(shù)字
# /dev/random和/dev/urandom都是隨機(jī)字符設(shè)備
0O8xmS]NKN[12:44:45 root@centos8-3 ~]#cat /dev/urandom | tr -dc '[:alnum:]' | head -c 10
mteifbL6l9[12:44:46 root@centos8-3 ~]#cat /dev/random | tr -dc '[:alnum:]' | head -c 10
GspCOBi05R[12:44:47 root@centos8-3 ~]#
tail命令
范例: 顯示ifconfig命令的第二行
[root@demo-c8 ~]# ifconfig | head -n2 | tail -1
inet 10.0.0.108 netmask 255.255.255.0 broadcast 10.0.0.255
tail -f: 跟蹤文件變化, 常用于跟蹤日志跟蹤
tail -f: 默認(rèn)顯示現(xiàn)有日志的最后十行, 從倒數(shù)第十行開始, 顯示到最新一行, 并且持續(xù)追蹤新發(fā)生的日志, 新發(fā)生的日志會(huì)追加顯示
-f: 追蹤文件描述符, fd, 即使文件被刪除, 也會(huì)持續(xù)追蹤, 因?yàn)槲募粍h除后, 文件描述符不會(huì)被刪除
-F: 追蹤文件名稱, 當(dāng)文件被刪除后, 追蹤停止, 如果新建了一個(gè)同名文件, 那么會(huì)重新追蹤
2.4 按列抽取文本cut
cut命令
當(dāng)分隔符連續(xù)出現(xiàn)時(shí), 比如df命令的結(jié)果, 如果用cut指定分隔符為空格時(shí), 連續(xù)的空格也會(huì)被算作一列, 此時(shí)要用tr -s先壓縮空格
格式:
cut [option]... [FILE]...
選項(xiàng):
-d DELIMITER: 指明分隔符,默認(rèn)tab
-f FIElDS:
#: 第#個(gè)字段,例如:3, 表示僅取第三個(gè)字段
#,#[,#]:離散的多個(gè)字段,例如:1,3,6
#-#:連續(xù)的多個(gè)字段, 例如:1-6
混合使用:1-3,7
-c 按字符切割顯示
--output-delimiter=STRING指定輸出分隔符, 比如按:為分隔符切割, 按照;為分隔符顯示
[root@demo-c8 ~]# cut -d: -f1 /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
games
ftp
nobody
dbus
systemd-coredump
systemd-resolve
tss
polkitd
geoclue
rtkit
...
[root@demo-c8 ~]# cut -d: -f1,3 /etc/passwd
root:0
bin:1
daemon:2
adm:3
lp:4
sync:5
shutdown:6
halt:7
mail:8
operator:11
games:12
ftp:14
...
[root@demo-c8 ~]# cut -d: --output-delimiter=";" -f1,3 /etc/passwd
root;0
bin;1
daemon;2
adm;3
lp;4
sync;5
shutdown;6
halt;7
mail;8
operator;11
games;12
...
范例: 顯示磁盤使用率, 按由大到小顯示
[root@demo-c8 ~]# df
Filesystem 1K-blocks Used Available Use% Mounted on
devtmpfs 3957252 0 3957252 0% /dev
tmpfs 3985420 0 3985420 0% /dev/shm
tmpfs 3985420 9832 3975588 1% /run
tmpfs 3985420 0 3985420 0% /sys/fs/cgroup
/dev/sda2 41922560 4542680 37379880 11% /
/dev/sda5 41922560 325336 41597224 1% /data
/dev/sda1 999320 192552 737956 21% /boot
tmpfs 797084 1168 795916 1% /run/user/42
tmpfs 797084 4 797080 1% /run/user/0
[root@demo-c8 ~]# df | tr -s " " | cut -d " " -f1,5 | tac | sort -k2 -r
Filesystem Use%
/dev/sda1 21%
/dev/sda2 11%
tmpfs 1%
tmpfs 1%
tmpfs 1%
/dev/sda5 1%
tmpfs 0%
tmpfs 0%
devtmpfs 0%
范例: 取本機(jī)ip地址
[root@demo-c8 ~]# ifconfig
ens160: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.0.108 netmask 255.255.255.0 broadcast 10.0.0.255
inet6 fe80::20c:29ff:fe97:37c8 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:97:37:c8 txqueuelen 1000 (Ethernet)
RX packets 45571 bytes 31757064 (30.2 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 31525 bytes 3744162 (3.5 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 48 bytes 4080 (3.9 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 48 bytes 4080 (3.9 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
virbr0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 192.168.122.1 netmask 255.255.255.0 broadcast 192.168.122.255
ether 52:54:00:86:db:73 txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@demo-c8 ~]# ifconfig | head -2 | tail -1
inet 10.0.0.108 netmask 255.255.255.0 broadcast 10.0.0.255
[root@demo-c8 ~]# ifconfig | head -2 | tail -1 | tr -s " " | cut -d" " -f3
10.0.0.108
2.5 合并多個(gè)文本paste
paste合并多個(gè)文件里相同行號(hào)的列到同一行
格式:
paste [OPTION]... [FILE]...
常用選項(xiàng):
-d 分隔符: 指定分隔符, 默認(rèn)為tab
-s: 所有行合成一行顯示, 默認(rèn)分隔符為tab
范例: 合并a.txt和b.txt
[root@demo-c8 ~]# vim a.txt
a
b
c
[root@demo-c8 ~]# vim b.txt
1
2
3




paste: 矩陣轉(zhuǎn)置, 將文件的列轉(zhuǎn)為行, 默認(rèn)分隔符為tab

用ls顯示目錄內(nèi)文件時(shí), 雖然是橫向顯示, 但是實(shí)際是縱向顯示每個(gè)文件的. 也可用ls -1來查看
[13:06:59 root@centos8-3 ~]#ls
anaconda-ks.cfg a.txt b.txt
[13:07:01 root@centos8-3 ~]#ls -1
anaconda-ks.cfg
a.txt
b.txt
2.6 分析文本的工具
2.6.1 收集文本統(tǒng)計(jì)數(shù)據(jù)wc
wc命令可以用來統(tǒng)計(jì)文件的行總數(shù), 單詞總數(shù), 字節(jié)總數(shù)和字符總數(shù)
可以對(duì)文件或者STDIN標(biāo)準(zhǔn)輸入中的數(shù)據(jù)進(jìn)行統(tǒng)計(jì)
常用選項(xiàng):
-l 只統(tǒng)計(jì)行數(shù)
-w 只統(tǒng)計(jì)單詞總數(shù). wc統(tǒng)計(jì)文本單詞個(gè)數(shù), 是以空格來區(qū)分單詞的
-c 只統(tǒng)計(jì)字節(jié)總數(shù)
-m 只統(tǒng)計(jì)字符總數(shù)
-L 顯示文件中最長(zhǎng)行的長(zhǎng)度
范例: 可以用ls | wc -l. 判斷目錄里有幾個(gè)文件. 如果需要統(tǒng)計(jì)隱藏文件就用ls -a
[13:07:46 root@centos8-3 ~]#ls
anaconda-ks.cfg a.txt b.txt
[13:07:49 root@centos8-3 ~]#ls | wc -l
3
范例: wc -L: 顯示文本中, 最長(zhǎng)一行的字符數(shù)
[root@demo-c8 ~]# cat /etc/passwd
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
[root@demo-c8 ~]# wc -L /etc/passwd
99 /etc/passwd
范例: wc FILE
[root@demo-c8 ~]# wc /etc/passwd
52 120 2901 /etc/passwd
文本行數(shù) 文本單詞數(shù) 文本字節(jié)數(shù)
[root@demo-c8 ~]# ll /etc/passwd
-rw-r--r--. 1 root root 2901 Sep 5 15:45 /etc/passwd
2.6.2 文本排序sort
sort把整理過的文本顯示在標(biāo)準(zhǔn)輸出上, 并不改變?cè)嘉募?/p>
格式:
sort [OPTIONS] FILE(s)
常用選項(xiàng):
-r 執(zhí)行反方向(由上至下)整理
-R 隨機(jī)排序
-n 執(zhí)行按數(shù)字大小整理
-f 忽略(fold)字符串中的字符大小寫
-u 選項(xiàng)(獨(dú)特,unique),合并重復(fù)項(xiàng),即去重
-t c 使用c做為字段界定符, 也就是指定分隔符, 默認(rèn)按照空格分隔
-k # 按照第幾列來排序
范例: 取出uid最大的前三行, 只顯示用戶名和uid
[root@demo-c8 ~]# cp /etc/passwd .
[root@demo-c8 ~]# cut -d: -f1,3 passwd | sort -t: -k2 -nr | head -3
nobody:65534
heiheiheihei:1004
heiheihei:1003
范例: 統(tǒng)計(jì)一共有多少個(gè)主機(jī)ip訪問了nginx服務(wù)器
cut -d" " -f1 /var/log/nginx/access_log | sort -u | wc -l
范例: 統(tǒng)計(jì)每個(gè)ip訪問了多少次
# 第一個(gè)sort是為了把所有的ip地址, 按照順序進(jìn)行排序, 這樣相同的ip就會(huì)連續(xù)出現(xiàn), 便于uniq做去重, 因?yàn)閡niq只有在相鄰的兩行是相同的內(nèi)容時(shí)才會(huì)去重
# uniq -c, 對(duì)ip地址進(jìn)行去重, 并且顯示每個(gè)ip地址出現(xiàn)的次數(shù)
# sort -k1 -nr, 按照第一列, 也就是相同ip出現(xiàn)的次數(shù)排序, 并且按照數(shù)字大小, 從大到小排序
[root@demo-c8 ~]# cut -d" " -f1 access_log | sort | uniq -c | sort -k1 -nr
4870 172.20.116.228
3429 172.20.116.208
2834 172.20.0.222
2613 172.20.112.14
2267 172.20.0.227
2262 172.20.116.179
2259 172.20.65.65
范例: 按照/etc/passwd中的uid字段把文本進(jìn)行排序
[13:13:46 root@centos8-3 /data/prac]#sort -t: -k 3 -n /etc/passwd
-t: 指定分隔符為冒號(hào), 指定第幾列, 要定義分隔符
-k 數(shù)字: 指定第幾列
-n: 如果指定的列都是數(shù)字, 想要按照數(shù)字大小排序, 需要-n, 默認(rèn)是按照ASCII碼順序, 從左到右,012...9AaBb...Zz, 從左到右比較每一位
范例: 對(duì)用戶名和uid,按照uid大小排序
[13:20:31 root@centos8-3 /data/prac]#cut -d: -f1,3 /etc/passwd | sort -t: -k 2 -n
[13:48:59 root@centos8-3 /data/prac]#cut -d' ' -f1 access_log | sort -u | wc -l
201
sort -u: 去重
sort 默認(rèn)就是從左到右, ASCII碼順序排序, 比較每一位, 012...9AaBb...Zz
2.6.3 去重uniq
如果相鄰的兩行是相同的, 那么uniq才會(huì)去重, 所以u(píng)niq只會(huì)對(duì)相鄰的兩行, 并且兩行內(nèi)容相同的情況下, 才會(huì)去重
uniq -c 顯示重復(fù)的個(gè)數(shù), 在每行顯示
[13:52:09 root@centos8-3 /data/prac]#cut -d' ' -f1 access_log | sort | uniq -c | sort -nr | head -1
4870 172.20.116.228
uniq -d 只顯示相鄰的重復(fù)的數(shù)據(jù)
uniq -u 只顯示沒有相鄰重復(fù)的
范例: lastb命令查看日志, 并且統(tǒng)計(jì)
- lastb顯示失敗的登錄記錄, 包含ip等
[14:08:31 root@centos8-3 /data/prac]#lastb -f btmp-34 | tr -s ' ' | cut -d ' ' -f3 | sort | uniq -c | sort -nr | head -10
86294 58.218.92.37
43148 58.218.92.26
18036 112.85.42.201
10501 111.26.195.101
10501 111.231.235.49
10501 111.204.186.207
10501 111.11.29.199
10499 118.26.23.225
6288 42.7.26.142
4236 58.218.92.30
面試題: 取兩個(gè)文件, 相同和不同的行? 兩個(gè)文件, 對(duì)應(yīng)的行, 哪些是相同的哪些是不同的
先通過cat打開兩個(gè)文件, 然后用sort排序, 默認(rèn)按照ASCII碼順序, 把相同的行排列到相鄰的位置, 再用uniq去重, -d會(huì)顯示相同的行, -u顯示不相同的行
cat FILE1 FILE2 | sort | uniq -d
cat FILE1 FILE2 | sort | uniq -u
[root@demo-c8 ~]# cat a.txt
a
b
1
2
c
[root@demo-c8 ~]# cat b.txt
1
2
3
# 相同的行
[root@demo-c8 ~]# cat a.txt b.txt | sort | uniq -d
1
2
# 不同的行
[root@demo-c8 ~]# cat a.txt b.txt | sort | uniq -u
3
a
b
c
2.6.4 比較文件
2.6.4.1 diff
diff命令可用于比較兩個(gè)文件之間的區(qū)別, diff命令的輸出可被保存在一種叫做補(bǔ)丁的文件中
常用選項(xiàng):
diff FILE1 FILE2
-u 詳細(xì)的顯示兩個(gè)文件的不同
范例: 比較a.txt和b.txt兩個(gè)文件的不同
[root@demo-c8 ~]# cat a.txt
a
b
1
2
c
[root@demo-c8 ~]# cat b.txt
1
2
3
[root@demo-c8 ~]# diff a.txt b.txt
1,2d0
< a
< b
5c3
< c
---
> 3
# -u選項(xiàng)會(huì)以后面的文件為基準(zhǔn), 逐行進(jìn)行比較
[root@demo-c8 ~]# diff -u a.txt b.txt
--- a.txt 2022-09-05 18:20:03.792540321 +0800 # -代表a.txt內(nèi)容
+++ b.txt 2022-09-05 16:18:21.047676537 +0800 # +代表b.txt內(nèi)容
@@ -1,5 +1,3 @@
-a # 比較第一行, 第一個(gè)文件需要把第一行a刪除, 才能和第二個(gè)文件一致
-b # 比較第二行, 第一個(gè)文件需要把第二行b刪除, 才能和第二個(gè)文件一致
1 # 第一個(gè)文件的a和b刪除后, 兩個(gè)文件的第一行就是一致的了, 為1
2 # 第一個(gè)文件的a和b刪除后, 兩個(gè)文件的第二行就是一致的了, 為2
-c # 第一個(gè)文件的第五行c需要被刪除, 才能和第二個(gè)文件一致
+3 # 第一個(gè)文件需要加一行3, 才能和第二個(gè)文件一致
2.6.4.2 patch
diff命令的結(jié)果可以通過重定向輸出到一個(gè)文本文件里, 基于這個(gè)文件, 可以用第一個(gè)文件還原出第二個(gè)文件
patch命令需要謹(jǐn)慎使用, 因?yàn)槟J(rèn)情況下, patch命令會(huì)丟失第一個(gè)文件
范例: 將a.txt和b.txt的diff結(jié)果輸出到文本中, 通過a.txt和diff結(jié)果, 還原出b.txt
[root@demo-c8 ~]# diff -u a.txt b.txt > diff.log
[root@demo-c8 ~]# rm -rf b.txt
# 默認(rèn)情況下, patch會(huì)把還原回來的文件命名成a.txt, 需要用-b選項(xiàng), 先把a(bǔ).txt進(jìn)行備份
[root@demo-c8 ~]# patch -b a.txt diff.log # -b會(huì)把a(bǔ).txt先進(jìn)行備份
patching file a.txt
[root@demo-c8 ~]# cat a.txt # 此時(shí), 新生成的a.txt為原來的b.txt
1
2
3
[root@demo-c8 ~]# cat a.txt.orig # .orig為備份的原來的a.txt
a
b
1
2
c
練習(xí)
1、找出ifconfig “網(wǎng)卡名” 命令結(jié)果中本機(jī)的IPv4地址
[root@demo-c8 ~]# ifconfig | head -2 | tail -1 | tr -s ' ' | cut -d" " -f3
10.0.0.108
2、查出分區(qū)空間使用率的最大百分比值
[root@demo-c8 ~]# df | tr -s " " | cut -d " " -f1,5 | tac | sort -k2 -r
Filesystem Use%
/dev/sda1 21%
/dev/sda2 12%
tmpfs 1%
tmpfs 1%
tmpfs 1%
/dev/sda5 1%
tmpfs 0%
tmpfs 0%
devtmpfs 0%
[root@demo-c8 ~]# df | tr -s " " %| cut -d "%" -f5 | tr -d "[:alpha:]" | sort -nr
21
12
1
1
1
1
0
0
0
[root@demo-c8 ~]#
3、查出用戶UID最大值的用戶名、UID及shell類型
[root@demo-c8 ~]# cut -d":" -f1,3,7 /etc/passwd | sort -t":" -k2 -nr | head -1
nobody:65534:/sbin/nologin
4、查出/tmp的權(quán)限,以數(shù)字方式顯示
[root@demo-c8 ~]# stat /tmp
File: /tmp
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: 802h/2050d Inode: 33555360 Links: 10
Access: (1777/drwxrwxrwt) Uid: ( 0/ root) Gid: ( 0/ root)
Context: system_u:object_r:tmp_t:s0
Access: 2022-09-05 14:41:10.010785301 +0800
Modify: 2022-09-05 19:03:01.535492239 +0800
Change: 2022-09-05 19:03:01.535492239 +0800
Birth: -
[root@demo-c8 ~]# stat /tmp | head -4 | tail -1 | cut -d " " -f2 | cut -d "/" -f1 | tr -dc "[:alnum:]"
1777[root@demo-c8 ~]#
5、統(tǒng)計(jì)當(dāng)前連接本機(jī)的每個(gè)遠(yuǎn)程主機(jī)IP的連接數(shù),并按從大到小排序
[root@demo-c8 ~]# ss -nt
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 52 10.0.0.108:22 10.0.0.1:54263
[root@demo-c8 ~]# ss -nt | grep "^ESTAB" | tr -s " " | cut -d" " -f5 | sort | uniq -c | sort -nr
1 10.0.0.1:54263
