Linux文本處理三劍客之sed詳解

一、sed工具介紹
sed是一種流編輯器,是一個面向行的處理工具,可以實現對文本的增刪改查和替換,可以同時處理多個文件多行內容,可以通過不同的方式去處理文本得到自己想要的結果,是一個功能非常強大的文本編輯處理工具。

二、sed的基本使用
用法1:前置命令 | sed [選項] ‘條件指令’
用法2:sed [選項] ‘條件指令’ 文件

相關說明如下:
條件可以是行號或者/正則/
沒有條件時,默認爲所有條件
指令可以是增、刪、改、查等指令
默認sed會將所有輸出內容都打印出來,可以使用-n屏蔽默認輸出
選項中可以使用-r選項,讓sed支持擴展正則

sed命令的常用選項如下:

選項 作用
-n 屏蔽默認輸出,默認sed會輸出讀取文檔的全部內容
-r 可以使用sed支持擴展正則
-i 使sed直接修改源文件,默認sed只是通過內存臨時修改文件,源文件無影響
指令 作用
p 打印
d 刪除
s 替換
a 追加,在指定的行之後追加文本
i 插入,在指定的行之前插入文本
c 替換行,替換指定的行

sed命令的-n選項

執行p打印等過濾操作時,希望看到的是符合條件的文本。但不使用任何選項時,默認會將原始文本一併輸出,從而干擾過濾效果。比如,嘗試用sed輸出/etc/hosts的第1行:
在這裏插入圖片描述
可以發現所有的行都被顯示出來了(第1行重複2次)。—— 正確的用法應該添加 -n 選項,這樣就可以只顯示第1行了:在這裏插入圖片描述
行號可以使連續的行號,如打印passwd第3行到第6行賬號信息:
在這裏插入圖片描述

sed命令-i選項:

正常情況下,sed命令所做的處理只是把操作結果(包括打印、刪除等)輸出到當前終端屏幕,而並不會對原始文件做任何更改,如下:
刪除/etc/hosts文件的所有內容,不加-i選項:
在這裏插入圖片描述
可以發現源文件的內容並沒有被修改,若是想直接修改源文件,則要添加選項-i,可以自己隨便創建一個文件試試,如下:
在這裏插入圖片描述

sed使用多個指令要用“;”(分號)隔離,如:
打印文件的第1行和第3行:
在這裏插入圖片描述
三、sed工具的條件使用:
sed [選項] ‘條件指令’ 文件
sed命令可以使用行號或正則作爲條件匹配:
##使用d指令跟p指令同理,只要把p換成d就可以了
1.行號案例:

[root@redhat ~]#sed -n '2p' /etc/passwd      //打印文件第2行
[root@redhat ~]#sed -n '3,5p' /etc/passwd    //打印文件第3到5行
[root@redhat ~]# sed -n '3p;5p' /etc/passwd  //打印文件的第3行和第5行`
[root@redhat ~]#sed -n '3,+10p' /etc/passwd  //打印文件第3行及第3行後面的10行
[root@redhat ~]#sed -n '1~2p' /etc/passwd    //打印文件第1行以及後面每隔兩行打印一次,也就是打印奇數行 
[root@redhat ~]#sed -n '2~2p' /etc/passwd    //打印文件第2行以及後面每隔兩行打印一次,也就是打印偶數行 

2.正則案例:

[root@redhat ~]#sed -n '/root/p' /etc/passwd      //打印文件中包含root的行
[root@redhat ~]#sed -n '/bash$/p' /etc/passwd     //打印文件中以bash結尾的行
[root@redhat ~]#sed -n 'p' /etc/passwd            //沒有條件,表示匹配所有的行,也就是會輸出文件中所有的內容
[root@redhat ~]#sed -n '$=' /etc/passwd           //輸出文件的行數
[root@redhat ~]#sed -n '/^$/d /etc/passwd         //刪除文件的空行
[root@redhat ~]#sed -n /root/!d' /etc/passwd      //刪除不包含root的行,!表示取反

3.sed工具的替換功能:
用法:sed ‘s/舊內容/新內容/選項’ 文件
注意:替換操作的分隔符"/"可以改用爲其他的字符代替,例如#,$,&等
sed工具的s指令替換案例集錦:

[root@redhat ~]#sed 's/aaa/AAA/' filename          //將每行中的第1個aaa替換爲AAA
[root@redhat ~]#sed 's/aaa/AAA/3' filename         //將每行中的第3個aaa替換爲AA
[root@redhat ~]#sed 's/aaa/AAA/g' 文件名            //將文件中所有的aaa替換爲AAA
[root@redhat ~]#sed -n '1s/aaa/AAA/p'  filename     //將文件第1行的第一個aaa替換爲AAA
[root@redhat ~]#sed -n '1s/aaa/AAA/gp' filename     //將文件第1行的所有aaa全替換爲AAA
[root@redhat ~]#sed 's/aaa//g' filename             //將文件中所有的aaa替換爲空(也就是刪除aaa)
[root@redhat ~]#sed 's#/bin/bash#/bin/sh#g' /etc/passwd    //將/etc/passed文件中的所有/bin/bash替換爲/bin/sh
[root@redhat ~]#sed '3,5s/^/#/' filename      //在文件中的第3-5行前面加上#號,也就是把第3-5行註釋掉
[root@redhat ~]#sed 's/^#a/a/' filename       //將文件中以a開頭的行的註釋去掉,刪除#號

四、sed工具使用案例:
參考數據文件內容如下:

[root@redhat ~]#cat a.txt
wo shi redhat7
ni shi centos6
1.刪除文件中每一行的第二個和最後一個字符:
思路:可以分爲兩步操作,先替換掉第2個字符,再替換掉最後一個字符;
[root@redhat ~]#sed 's/.//2;s/.$//' a.txt

2.將文件中每一行的第一個和倒數第一個字符互換位置:
思路:每行的文本的內容可以拆分爲“第1個字符”、“中間的字符”、“倒數第一個字符”三個部分,然後通過替換操作配合正則重新將文檔的內容重新排序;

[root@redhat ~]#sed -r 's/^(.)(.*)(.)$/\3\2\1/' a.txt

3.刪除文件中的數字:

[root@redhat ~]#sed -r 's/[0-9]//' a.txt

4.刪除文件每行倒數第2個字符:
思路:每行的文本的內容可以拆分爲“前面的字符”、“倒數第2個字符”、“倒數第一個字符”三個部分,通過替換操作配合正則重新將文檔的內容重新排序將倒數第二個字符去掉;

[root@redhat ~]#sed -r 's/^(.*)(.)(.)$/\1\3/' a.txt

5.刪除文件的第二個單詞:
思路1:可以將每一行的內容分爲五個部分,“第一個單詞”,“空格”,“第二個單詞”,“空格”,“第三個單詞”,然後通過替換操作將每一行重新排序去掉第二個單詞,下面每一行就是一種處理方法:

[root@redhat ~]#sed -r 's/(.+)([^a-Z0-9])([a-Z0-9]+)([^a-Z0-9])([a-Z0-9]+)/\1\2\4\5/' a.txt
[root@redhat ~]#sed -r 's/([a-Z0-9]+)([^a-Z0-9])([a-Z0-9]+)([^a-Z0-9])([a-Z0-9]+)/\1\2\4\5/' a.txt
[root@redhat ~]#sed -r 's/([a-Z0-9]{1,})([^a-Z0-9])([a-Z0-9]{1,})([^a-Z0-9])([a-Z0-9]{1,})/\1\2\4\5/' a.txt
[root@redhat ~]#sed -r 's/([a-Z0-9]+)([^a-Z0-9])(.*)([^a-Z0-9])([a-Z0-9]+)/\1\2\4\5/' a.txt
[root@redhat ~]#sed -r 's/([a-Z]+)([[:space:]])([a-Z0-9]+)([[:space:]])([a-Z0-9]+)/\1\2\4\5/' a.txt

思路2(適合不夠嚴謹的場合):將文件每行的內容分爲3部分,每一個單詞爲一個部分,不管空格,然後通過替換操作將每一行重新排序去掉第二個單詞,同時在第一跟第三個單詞之間加上tab鍵,可以將第一跟第三個單詞隔開,下面每一行就是一種處理方法:

[root@redhat ~]#sed -r 's/([a-Z]{1,}) ([a-Z]{1,}) ([a-Z]{1,})/\1\t\3/' a.txt
[root@redhat ~]#sed -r 's/([a-Z]+) ([a-Z]+) ([a-Z]+)/\1\t\3/' a.txt
[root@redhat ~]#sed -r 's/(.+) ([a-Z]+) ([a-Z]+)/\1\t\3/' a.txt

6.將文件中每一行的第一個單詞跟最後一個單詞調換位置:
思路:思路跟上面差不多,同樣是將文件中的內容分爲五部分,“第一個單詞”,“空格”,“第二個單詞”,“空格”,“第三個單詞”,然後通過替換操作將每一行重新排序將第一個單詞跟組後一個單詞調換位置(12345–>52341),下面每一行就是一種處理方法:

[root@redhat ~]# sed -r 's/([a-Z0-9]+)([^a-Z0-9])(.*)([^a-Z0-9])([a-Z0-9]+)/\5\2\3\4\1/' a.txt
[root@redhat ~]# sed -r 's/([a-Z0-9]+)([^a-Z0-9])([a-Z0-9]+)([^a-Z0-9])([a-Z0-9]+)/\5\2\3\4\1/' a.txt
**#不同的方法可以參考上面**

五、利用sed工具修改系統配置(當前使用的是redhat7.4版本的系統),如下:
編寫腳本vsftp.sh,修改簡單修改服務配置,實現以下任務需求:
任務需求:
通過yum安裝vsftpd軟件包
修改vsftpd服務配置,開啓匿名上傳
調整/var/ftp/pub目錄權限,允許寫入
啓動vsftpd服務,並設置開機自運行
思路分析:
a.vsftpd服務的安裝、改目錄權限、起服務等操作可以直接寫在腳本中。
b.修改vsftpd.conf配置的工作可以使用sed命令,根據默認配置,只需要定位到以#anon開頭的行,去掉開頭的註釋即可。

[root@redhat ~]# vim vsftp.sh

#!/bin/bash
yum -y install vsftpd                //安裝vsftpd軟件				
cp /etc/vsftpd/vsftpd.conf{,.bak}    //備份默認的配置文件,新的文件命名爲vsftpd.conf.bak,同樣在/etc/vsftpd/目錄下
sed -i "s/^#anon/anon/" /etc/vsftpd/vsftpd.conf   //修改服務配置
chmod 777 /var/ftp/pub       //調整目錄權限
systemctl start vsftpd      //啓動服務
systemctl enable vsftpd    //將服務設置爲開機自啓動

[root@redhat ~]# chmod +x vsftp.sh  //給腳本賦予執行權限
[root@redhat ~]# ./vsftp.sh        //運行腳本驗證

六、sed多行文本處理
用法:sed [選項] ‘條件指令’ 文件
sed工具的多行文本處理操作:
i: 在指定的行之前插入文本
a:在指定的行之後追加文本
c:替換指定的行

[root@redhat ~]#sed  '2a XX'   a.txt //在第二行後面,追加XX
[root@redhat ~]#sed  '2i XX'   a.txt //在第二行前面,插入XX
[root@redhat ~]#sed  '2c XX'   a.txt  ////將第二行替換爲XX
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章