概述:
本篇我們主要學習兩個功能非常強大的文本編輯器,了解這兩種文本編輯器的各自的特點
一、sed命令:
1、sed簡介:
sed(Stream EDitor)是一種流編輯器、行編輯器。逐行處理文本內容,即一次處理一行內容,處理時,當前處理的行存儲在“模式空間”(pattern space)中,接著用sed命令模式空間中的內容,處理完畢后,把模式空間中的內容送到標準輸出;然后處理下一行,重復完成相同的操作直至文件末尾。
sed處理文件時,不會對原文件的內容進行修改,除非用選項-i直接編輯原文件或重定向至原文件存儲處理后的結果。
sed主要用來幫助用戶自動編輯一個或數個文件,并簡化對文件反復操作過程。所以sed是一種非交互式的文本編輯工具(通過用戶給定的條件自動逐行處理對應文件)。
2、sed的使用:
使用格式
sed [OPTION]… {script-only-if-no-other-script} [input-file]…
簡化理解為:sed [OPTION]…{script} [input-file]… 常用選項(OPTION):
-n:不輸出模式空間的內容至屏幕
-e:script,–expression=script:多點編輯
eg:
sed -e "s@^#[[:spcae:]]*@@" -e "/^UUID/d" /etc/fstab
-f /PATH/TO/SED_SCRIPT_FILE 每行一個編輯命令的sed腳本
-r:–regexp-extended:支持使用擴展正則表達式
-i[SUFFIX],–in-place[=SUFFIX]:直接編輯原文件
注意:-i.后綴名 可以先備份文件,然后在原文件處編輯
script:地址定界編輯命令,有兩部分組成,彼此之間相鄰,不分割
地址定界:指定編輯范圍
(1)不給地址-空地址:對全文進行處理
eg:
sed 's/^UUID/UID/' /etc/fstab
(2)單地址:
#:指定行 數字
eg:
sed '2d' /etc/fstab #刪除第二行(原文件沒變)
/pattern/:被此模式所匹配的每一行
eg:
sed '/UUID/d' /etc/fstab #刪除存在UUID的行
(3)地址范圍 (#為數字)
#,#:從第#行到第#行的所有行
#,+#:從第#行開始以及之后#行的所有行
eg : 3,+8 包括第3行以及第3行后面8行
#,/pat1/:從第#行到第一次匹配到/pat1/的行的所有行
/pat1/,/pat2/:從第一次匹配到/pat1/的行到第一次匹配到/pat2/的行
eg:
sed -n '/Created/,/Accessible/p' /etc/fstab
注意:如果sed匹配地址定界時能匹配到/pat1/,匹配不到/pat2/,則會從匹配到/pat1/的行開始一直到文尾;如果匹配不到/pat1/,則即使存在/pat2/,也不會匹配到對應的行
(4)步進:~ 隔幾行
1~2:奇數行:1、3、5、7、…
2~2:偶數行:2、4、6、8、…
3~5:3、8、13、18、….
編輯命令:確定編輯方式
d:刪除匹配的模式空間中的行
eg:
sed '2d' /etc/fstab #刪除第二行(原文件沒變)
p:顯示匹配的模式空間中的內容
eg:
sed -n '/Created/,/Accessible/p' /etc/fstab
a \text:在行后面追加文本"text",支持使用\n實現多行追加
eg:
sed '/UUID/a \aabbcc' /etc/fstab #在全文匹配到UUID的行后追加aabbcc這一行
i \text:在行前面插入文本"text",支持使用\n實現多行插入
sed '/UUID/i \aabbcc' /etc/fstab #在全文匹配到UUID的行前追加aabbcc這一行
c \text:用text替換匹配到的行
sed '/UUID/c \aabbcc' /etc/fstab #在全文匹配到UUID的行替換為aabbcc這一行
w /PATH/TO/SOMEFILE:保存模式空間匹配到的行至指定的文件中;
eg:
sed '2w /tmp/test' /etc/fstab #將/etc/fstab的第2行保存至/tmp/test中
r /PATH/TO/SOMEFILE:讀取指定文件的內容至當前文件被模式匹配到的行后面;文件合并
sed '2r /tmp/test' /etc/fstab #將/tmp/test的內容讀取追加至/etc/fstab第2行之后
=:為模式匹配到的行打印行號
sed '=' /etc/fstab #給所有行匹配行號
sed '/UUID/=' /etc/fstab #給匹配到的行加行號
注意:行號是按文件中原本行號顯示的
!:條件取反(放在地址定界后其他編輯命令前,否則報錯)
sed '/UUID/!=' /etc/fstab #給有UUID行意外的行加行號
s///:查找替換,其分隔符可自行制定,常用的有s@@@,s###等;
替換標記:
g:全局替換
我們在使用此編輯命令時,其實只是匹配到這一行的第一次匹配到的內容,這一行之后的內容就不會進行操作了,而g的作用就是這一行的所有能夠滿足匹配的內容
i:不區分大小寫
p:顯示替換成功的行
就是操作成功的行會顯示一遍,一般和-n搭配
w /PATH/TO/SOMEFILE:將替換成功的結果保存至指定文件中
練習1:刪除/boot/grub/grub2.cfg文件中的所有以空白字符開頭的行的行首的所有空白字符;
sed "s@^[[:space:]]\+@@" /boot/grub/grub2.cfg
練習2:刪除/etc/fstab文件中所有以#開頭的行的行首的#號及#后面的所有空白字符;
sed "s@^#[[:spcae:]]*@@" /etc/fstab
練習3:輸出一個絕對路徑給sed命令,取出其目錄,其行為類似于dirname;
echo "/etc/passwd" | sed "s@[^/]\+/\?$@@"
sed命令除了“模式空間”(pattern space),還有一個“hold space”的內存空間,叫保存空間。
sed工作機制是每次讀取一行文本至“模式空間”中,在模式空間中完成處理,并將處理后的結果輸出至標準輸出設備;但是有的時候我們處理完一行后,開始處理另一行,對處理過的行可能還有其他操作,因此sed還有一個“保存空間”,先把處理過的行放到保存空間中,然后后續的處理中再拿回到模式空間中進行處理。
模式空間就好像加工車間而保存空間就相當于“半成品倉庫”。
sed的高級編輯命令就是運用于保存空間的
高級編輯命令:
h:把模式空間中的內容覆蓋至保持空間中;(模式空間復制一份覆蓋保持空間)
H:把模式空間中的內容追加至保持空間中;(模式空間復制一份追加至保持空間內容的后面)
g:把保持空間中的內容覆蓋至模式空間中;
G:把保持空間中的內容追加至模式空間中;
x:把模式空間中的內容與保持空間中的內容互換;
n:讀取匹配到的行的下一行至模式空間中;并覆蓋匹配到的行
N:讀取匹配到的行的下一行至模式空間中;并追加匹配到的行后面.
d:刪除模式空間中的行
D:刪除多行模式空間中的所有行;
示例:
sed -n 'n;p' FILE :顯示偶數行
sed '1!G;h;$!d' FILE :逆序行顯示文件內容
sed '$!d' FILE :取出最后一行
sed '$!N;$!D' FILE:取出最后兩行
sed '/^$/d;G' FILE:刪除原有的所有空白行,而后為所有的非空白行后添加一個空白行;
sed 'G' FILE :在原有的每行后方添加一個空白行
是不是有點暈?
為了幫助大家更好的理解sed工作機制,我重申一下以下內容
注意:sed是流編輯器、行編輯器;是逐行處理文件內容的,處理完一行才會處理下一行,最后處理完,并顯示結果;
那如何判斷這一行處理完成了那?
簡單的說就是開始第一次讀取處理A行的下一行B行時,就算A行處理完畢了,此時A行處理完畢如果還存在,則顯示,不存在則不顯示;sed工具對文件中的每行都只是逐行讀取處理一次!而保存空間中的內容是讀取處理完的內容復制保留下來的,不是重新從文件中讀取的。
通過以下示例我們逐一分析理解就可以明白sed命令的運行機制了
示例講解:
sed 'n;d' FILE;顯示奇數行文件內容
1、首先sed工具從FILE文件中提取第一行內容至模擬空間進行處理
n命令是讀取匹配到的行的下一行至模式空間中;并覆蓋匹配到的行
2、所以準備開始讀取處理第二行至模式空間(注意因為開始讀取第二行了,也就意味著第一行處理完畢,而此時n命令并沒有執行完成,就不能執行后續的d命令了,所以第一行的內容在處理完之后是沒有被后續的第二行覆蓋的,而沒有被d刪除,所以會在模式空間中顯示出來)
3、第二行內容進入模式空間覆蓋掉第一行內容,n命令才算結束,然后才可以開始執行d命令,也就是刪除此時模式空間中的第二行內容,此時模式空間中什么也沒有自然也不會顯示被刪除的第二行。
注意:sed命令只會逐行讀取處理行一次,因為第一行與第二行都已經讀取處理過一次了,所以下次會從第三行開始
4、以此類推,開始讀取第三行至模式空間…..
5、直至文件內容末尾
以上純為個人理解,并不是根據源代碼得出的結論,僅希望幫助大家理解sed工作機制
二、vi(vim)文本編輯器
vi:Visual Interface,是一中文本編輯器,所謂文本數據是基于字符編碼的文件,常見的編碼有ASCII編碼,UNICODE編碼等等
vim是全屏編輯器,編輯空間占據整個屏幕,類似的還有nano,與上文的sed行編輯器不一樣。
VIM及Vi IMproved:vi的增強版,vim是模式化的編輯。
vim是交互式編輯器同樣與sed編輯器有著不同
vim:模式化的編輯器
工作模式:
編輯模式:命令模式
輸入模式
末行模式:內置的命令行接口
打開文件:
vim [options] [file ..]
vim [options] –
vim [options] -t tag
vim [options] -q [errorfile]
+#:打開文件后,直接讓光標處于第#行的行首
+/PATT:打開文件后,直接讓光標處于第一個被PATTERN匹配到的行的行首
+:打開文件后,直接讓光標處于尾行行首
模式轉換:
編輯模式:默認模式
編輯模式–>輸出模式:
i:isert,在光標所在處輸入;
a:appeng,在光標所在處后方輸入;
o:在光標所在處下方打開的一個新行;
I:在光標所在行的行首輸入;
A:在光標所在行的行尾輸入;
O:在光標所在處上方打開的一個新行;
輸入模式–>編輯模式
ESC(可以兩次)
編輯模式–>末行模式
:
末行模式–>編輯模式
ESC(可以兩次)
關閉文件
編輯模式:
ZZ:保存并退出
ZQ:不保存退出
末行模式:
:q 退出
:q!強制提出,不保存此前的編輯操作
:wq保存并推出
:w,:q
:x 保存并退出
:w /PATH/TO/SOMEFILE 另存為
光標跳轉:
字符間跳轉:
k:上
h:左 l:右
j:下
#COMMAND:跳轉由#指定的個數的字符
單詞間跳轉
w:下一個單詞的詞首
e:當前或后面一個單詞的詞尾
b:當前或前一個單詞的詞首
#COMMAND :跳轉由#指定的個數的單詞
行首行尾跳轉
^:跳轉至行首的第一個非空白字符
0:跳轉至行首(絕對行首但是不包括tab符)
$:跳轉至行尾(絕對行尾即使有空白字符)
行間跳轉
#G:跳轉至由#指定的行
1G,gg:第一行
G:最后一行
句間跳轉
):后一句
(:前一句
#):后幾句
…
段間跳轉
{:前一段
}:后一段
翻屏:
Ctrl+f:向文件尾部翻一屏
Ctrl+b:向文件首部翻一屏
Ctrl+d:向文件尾部翻半屏
Ctrl+u:向文件首部翻半屏
Enter:向文件尾部翻一行
鎖定和解鎖:CTRL+s,Ctrl+q
當前頁跳轉:
H :頁首 M行 :頁中間行 L: 頁底
vim的編輯命令
字符編輯:
x:刪除光標所在處的字符
#x:刪除光標所在處起始的#個字符
xp:交換光標所在處的字符與其后面的字符的位置
~:轉換光標所在處的字符大小寫eg: a-A B-b
替換命令(replace):
r(后面跟要換的字符):替換光標所在處的字符;
刪除命令:
d:刪除命令,科技和光標跳轉字符,實現范圍刪除
d$:刪除當前光標處到行尾的內容
d^:刪除當前光標處到行首的內容
以下支持#COMMAND
dw:刪除當前光標處到下一個單詞的詞首的內容
#dw刪除當前光標處到下#個單詞的詞首的內容
de:刪除當前光標處到當前或后面一個單詞的詞尾的內容
#de刪除當前光標處到當前或后面#個單詞的詞尾的內容
db:刪除當前光標處到當前或前一個單詞的詞首的內容
#db刪除當前光標處到當前或前#個單詞的詞首的內容
dd:刪除光標所在處的行;
#dd:刪除光標所處的行起始的共#行
D: : 從當前光標位置一直刪除到行尾,留空行,等同于d$
粘貼命令:(p,put,paste)
p:緩沖區中的內容如果為整行,則粘貼在當前光標所在行的下方;否則,則粘貼至當前光標所在處的后方;
P:緩沖區中的內容如果為整行,則粘貼在當前光標所在行的上方;否則,則粘貼至當前光標所在處的前方;
復制命令(yank,y):
y:復制,工作行為類似于d命令
y$:復制當前光標處到行尾的內容
y^:復制當前光標處到行首的內容
y0:復制當前光標處到絕對行首的內容
以下支持#COMMAND
ye:復制當前光標處到當前或后面一個單詞的詞尾的內容
#ye復制當前光標處到當前或后面#個單詞的詞尾的內容
yw:復制當前光標處到下一個單詞的詞首的內容
#yw復制當前光標處到下#個單詞的詞首的內容
yb:復制當前光標處到當前或前一個單詞的詞首的內容
#yb復制當前光標處到當前或前#個單詞的詞首的內容
yy:復制光標所在處的一整行
#yy:復制光標所處的行起始的共#行
Y:復制整行
改變命令(change,c):
編輯模式–>輸入模式,實現刪除操作;并可以進行輸入模式
c$:改變當前光標處到行尾的內容
c^:改變當前光標處到行首的內容
c0:改變當前光標處到絕對行首的內容
以下支持#COMMAND
ce:改變當前光標處到當前或后面一個單詞的詞尾的內容
#ye改變當前光標處到當前或后面#個單詞的詞尾的內容
cw:改變當前光標處到下一個單詞的詞首的內容
#yw改變當前光標處到下#個單詞的詞首的內容
cb:改變當前光標處到當前或前一個單詞的詞首的內容
#cb改變當前光標處到當前或前#個單詞的詞首的內容
cc:改變光標所在處的一整行
#cc:改變光標所處的行起始的共#行
C:刪除當前光標到行尾,并切換成插入模式可修改內容
100i字符串 [ESC] 粘貼“字符串 ”100次
? <start position><command><end position>
? Command:
y 復制、d 刪除、gU 變大寫、gu 變小寫
可視化模式:(類似鼠標)
v:按字符選定
V:按行選定
ctrl-v 按塊選定
組合編輯命令:d刪除,c刪除并修改,y復制
撤銷(undo)操作:
u:撤銷此前的操作(保存最近50次的操作)
#u:撤銷此前#次操作
U:撤消光標落在這行后所有此行的更改
撤銷此前的撤銷操作:
Ctrl+r
重復執行前一個編輯操作:.
重復前一個操作n次: n.
vim自帶的練習教程:vimtutor
vim末行模式(擴展命令模式):Shift+;=:
內建的命令行接口
(1)地址定界 :start_pos[,end_pos]
.:當前行
$:最后一行
#:特定的第#行,例如5即第5行;
#,#:指定行范圍,左側為起始行,右側為結束行;
#,+#:指定行范圍,左側為起始行絕對編號,右側為相對于左側行號的偏移量;例如:3,+7
.,$-1:當前行到倒數第二行
1,$:第一行到最后一行
%:全文
/pattern/:從光標所在處起始向文件尾部第一次被模式所匹配到的行
/pattern1/,/pattern2/:從光標所在處起始,第一次由pat1匹配到的行開始,至第一次由pat2匹配到的行結束之間的所有行
可同編輯命令一同使用,實現編輯操作:
d刪除、y復制、c改變,直接跟在地址定界后,不分割
w /PATH/TO/SOMFILE:將選定的范圍內的內容保存至某文件中
r /PATH/FROM/SOMEFILE:將指定的文件中的內容讀取到指定位置
(2)查找
/PATTERN:從當前光標所在處向文件尾部查找能夠被當前模式匹配到的所有字符串;
?PATTERN:從當前光標所在處向文件首部查找能夠被當前模式匹配到的所有字符串;
n:下一個,與命令方向相同
N:上一個,與命令方向相反
(3)查找并替換
s:末行模式的命令;使用格式;
s/要查找的內容/替換的內容/修飾符
要查找的內容:可使用正則表達式;但不能使用正則表達式中的元字符
替換內容:不能使用正則表達式,但是可以引用;
如果“查找的內容”部分在模式中使用分組符號在“替換的內容”中使用后向引用
直接引用查找模式匹配到的全部文本,要使用&符號
修飾符:
i:查找時忽略大小寫
g:全局替換,意味著一行中如果匹配到多次,則均被替換
gc:全局替換,每次替換前詢問
%s/This/this/gi
可把分割符替換為其他非常用的字符:
s@@@
s###
(4)命令使用
!command 執行命令
r!command 讀入命令的輸出
以二進制方式打開文件
vim –b binaryfile
? 擴展命令模式下,利用xxd 命令轉換為可讀的十六進制
:%!xxd
? 編輯二進制文件
? 擴展命令模式下,利用xxd 命令轉換回二進制
:%!xxd –r
保存并退出
?
示例:
%s@\<t\([[:alpha:]]\+\)\>@T\1@g
%s@\<t[[:alpha:]]\+\>@&er@g
練習:Centos7版本
1、復制/etc/grub2.cfg文件至/tmp目錄中,用查找替換命令刪除/tmp/grub2.cfg文件中以空白字符開頭的行的行首的空白字符;
%s@^[[:space:]]\+@@g
2、復制/etc/rc.d/init.d/functions文件至/tmp目錄中,用查找替換命令為/tmp/functions文件的每個以空白字符開頭的行首加上#;
%s@^[[:space:]]\+[^[:space:]]@#&@g
3、為/tmp/grub2.cfg文件的前三行的行首加上#號
1,3s@^[[:space:]]\+[^[:space:]]@#&@g
4、將/etc/yum.repos.d/CentOS-Base.repo文件中所有的enabled=0替換為enabled=1,所有gpgcheck=0替換為gpgcheck=1;
%s@\(enabled\|gpgcheck\)=0@\1=1@g
vim多文件功能
多文件(一次打開多個文件)
vim FILE1 FILE2 …
文件間切換
:net切換到下一個文件
:previous切換到上一個文件
:last 最后一個
:first 第一個
退出所有文件
:wqall 保存所有文件并退出
:wall 保存所有文件
:qall 退出不保存所有文件
多窗口:
多文件
vim -o FILE1 FILE2 …
-o:水平分割窗口
-O:垂直分割窗口
窗口間切換Ctrl+w,Arrow(上下左右箭頭)
單文件:(分割多個窗口)
Ctrl+w,s:水平分割
Ctrl+w,v:垂直分割
ctrl+w,q :取消相鄰窗口
ctrl+w,o: 取消全部窗口
定制vim 的工作特性
末行模式(擴展模式):自此模式下的設定,僅對當前vim進程有效
配置文件:永久有效
全局:/etc/vimrc
個人:~/.vimrc(可能需要用戶自己創建,格式逐一羅列每行一個)
(1)行號
顯示:set number, 簡寫為set nu
取消顯示:set nonumber, 簡寫為set nonu
(2)括號成對匹配高亮
匹配:set showmatch, 簡寫為set sm
取消:set noshowmatch, 簡寫為set nosm
(3)自動縮進
啟用:set ai
禁用:set noai
(4)高亮搜索
啟用:set hlsearch
禁用:set nohlsearch
(5)語法高亮
啟用:syntax on
禁用:syntax off
(6)忽略字符的大小寫
啟用:set ic
不忽略:set noic
配置 vi and vim
(7)文件格式
啟用windows 格式:set fileformat=dos
啟用unix 格式:set fileformat=unix
(8)設置文本寬度
:set textwidth=65 (vim only)
:set wrapmargin=15
:help option-list
:set or :set all
?
vi/vim 內置幫助
:help
:help subject(關鍵詞主題)
eg::help topic
:help set
練習和課后作業
1 、刪除/etc/grub2.conf 文件中所有以空白開頭的行行首的空白字符
sed "s/^[[:space:]]\+//" /etc/grub2.cfg
sed -r "s/^[[:space:]]+//" /etc/grub2.cfg
2 、刪除/etc/fstab 文件中所有以# 開頭,后面至少跟一個空白字符的行的行首的#和空白字符
sed -r "s/^#[[:space:]]+//" /etc/fstab
sed "s/^#[[:space:]]\+//" /etc/fstab
3 、在/root/install.log 每一行行首增加#號
sed -r "s/^.*/#&/" /root/install.log
sed -r "s/(.*)@#\1/g" /root/install.log
sed "s/^/#/" /root/install.log
4 、在/etc/fstab文件中不以#開頭的行的行首增加#號
sed -r "s/^[^#]/#&/" /etc/fstab
5 、處理/etc/fstab路徑, 使用sed 命令取出其目錄名和基名
echo /etc/fstab | sed -r "s/^\/.*\<//" #基名
echo /etc/fstab | sed -r "s/([^/]+\/?)$//" #目錄名
echo "/etc/fst/sd" | sed -r 's/(.*/)([^/]+/?)$/\1/' #基名用\2 目錄名\1
6 、利用sed取出ifconfig 命令中本機的IPv4 地址
ifconfig | sed -n "2p" |sed -r "s/^[^:]+\://" | sed -r "s/[[:space:]].*//"
ifconfig|sed -n 2p |sed -r 's/.*addr:(.*) Bca.*/\1/'
ifconfig|sed -n 2p |sed -e 's/.*addr://' -e 's/ B.*//'
ifconfig|sed -n 2p |sed -r 's/.*addr:(.*) Bca.*/\1/'
7 、統計centos 安裝光盤中Package 目錄下的所有rpm 文件的以.分隔倒數第二個字段的重復次數
CentOS6.8
ls /media/CentOS_6.8_Final/Packages/*.rpm |egrep -o "[^.]+.rpm$"|egrep -o "^[^.]+\>"
ls /media/CentOS_6.8_Final/Packages/*.rpm |sed -r "s/\.rpm$//" | sed -r "s/.*\<//"
CentOS7.2
ls /run/media/root/CentOS\ 7\ x86_64/Packages/*.rpm |egrep -o "[^.]+.rpm$"|egrep -o "^[^.]+\>"
ls /run/media/root/CentOS\ 7\ x86_64/Packages/*.rpm |sed -r "s/\.rpm$//" | sed -r "s/.*\<//"
8、如何設置tab縮進為4個字符?
vim ~/.vimrc set tabstop=4 #tabstop=ts source ~/.vimrc
為了加強對比度,我們可以吧tabstop的值設為16,對比一下兩者的效果
9、復制/etc/rc.d/init.d/functions文件至/tmp目錄;替換/tmp/functions文件中的/etc/sysconfig/init為/var/log;
cp /etc/rc.d/init.d/functions /tmp vim /tmp/functions
用vim打開文件后按住shift鍵單擊 :鍵 從命令模式(編輯模式)進去到插入模式(輸入模式)
輸入 %s@/etc/sysconfig/init@/var/log@gi 回車
再次進去插入模式(輸入模式)
輸入 wq 保存并退出
10、刪除/tmp/functions文件中所有以#開頭,且#后面至少有一個空白字符的行的行首的#號;
vim /tmp/functions
用vim打開文件后按住shift鍵單擊 :鍵 從命令模式(編輯模式)進去到插入模式(輸入模式)
輸入 %s@^#\([[:space:]]\+.*\)@\1@g 回車
再次進去插入模式(輸入模式)
輸入 wq 保存并退出
未完待續
原創文章,作者:NameLess,如若轉載,請注明出處:http://www.www58058.com/35052