Shell程式設計正規表示式sed

2020-11-14 11:00:39

目錄

定義

sed (Stream EDitor)是一個強大而簡單的文字解析轉換工具,可以讀取文字,並根據指定的條件對文字內容進行編輯(刪除替換,新增,移動等),最後輸出所有行或者僅輸出處理的某些行。

工作流程

  • 讀取:sed 從輸入流(檔案,管道,標準輸入)中讀取一行內容並儲存到臨時的快取區中(又稱模式空間,pattern space)。
  • 執行:預設情況下。所有的sed命令都在模式空間中順序地執行,除非指定了行的地址,否則sed命令將會在所有的行上依次執行。
  • 顯示:傳送修改後的內容到輸出流。在傳送資料後,模式空間將會被清空。

在所有的檔案內容都被處理完成之前,上述過程將重複執行,直至所有內容被處理完。
注:預設情況下所有的sed命令都是在模式空間內執行的,由此輸入的檔案並不會發生任何變化,除非是用重定向儲存輸出。

常見用法

  • sed [選項] ‘操作’ 引數
  • sed [選項] -f scriptfile 引數

常見的sed命令選項主要包含以下幾種

  • -e script(指令碼命令) : 指定sed編輯命令
  • -f scriptfile(檔案) : 指定的檔案中是sed編輯命令
  • -h 或 --help :顯示幫助
  • -n,–quiet 或 silent :表示僅顯示處理後的結果
  • -i :直接編輯文字檔案(會對檔案產生變化)

常見的操作包含以下幾種

  • a: 增加,在當前行下面增加一行指定內容
  • c:替換,將選定行替換為指定內容
  • d:刪除,刪除選定的行
  • i:插入,在選定行上面插入一行指定內容
  • p:列印,如果同時指定行,表示列印指定行;如果不指定行,則表示列印所有內容;如果有非列印字元,則以ASCII碼輸出。其通常與「-n」選項一起使用。(輸出)
  • s:替換,替換指定字元
  • y:字元轉換

輸出內容

帶行號輸出所有內容 等同於 cat test.txt

[root@server2 ~]# nl test.txt | sed -n 'p'

在這裡插入圖片描述

輸出第4行,或者3到5行

[root@server2 ~]# nl test.txt | sed -n '4p'
[root@server2 ~]# nl test.txt | sed -n '3,5p

在這裡插入圖片描述

輸出偶數行;奇數行

[root@server2 ~]# nl test.txt | sed -n 'n;p'
[root@server2 ~]# nl test.txt | sed -n 'p;n'

在這裡插入圖片描述

輸出1到6行之間的偶數行,3到9行之間的奇數行

[root@server2 ~]# nl test.txt | sed -n '1,6{n;p}'
[root@server2 ~]# nl test.txt | sed -n '3,9{p;n}'

在這裡插入圖片描述

輸出以第6行到結尾之間的偶數行(即以第6行為起始行,重新排序設定)

[root@server2 ~]# nl test.txt | sed -n '6,${n;p}'

在這裡插入圖片描述

輸出包含the的內容

[root@server2 ~]# sed -n '/the/p' test.txt

在這裡插入圖片描述

輸出從第3行開始到第一個包含the的行(是一個區間過程)

[root@server2 ~]# nl test.txt | sed -n '3,/the/p' 

在這裡插入圖片描述

輸出包含the的所在行的行號(等號用來輸出行號)

[root@server2 ~]# sed -n '/the/=' test.txt

在這裡插入圖片描述

輸出以PI為開頭的內容;以0到9數位為結尾的內容

[root@server2 ~]# sed -n '/^PI/p' test.txt
[root@server2 ~]# sed -n '/[0-9]$/p' test.txt

在這裡插入圖片描述

輸出包含單詞home的行(<> 代表單詞邊界)

[root@server2 ~]# sed -n '/\<home\>/p' test.txt
[root@server2 ~]# grep 'home' test.txt 

在這裡插入圖片描述

  • 注:nl :命令用於計算檔案的行數

刪除內容

刪除第5行;刪除2到4行

[root@server2 ~]# nl test.txt | sed '5d'
[root@server2 ~]# nl test.txt | sed '2,4d'

在這裡插入圖片描述

僅在外部輸出刪除,不會對原始檔產生影響

刪除除了包含單詞home的內容的其它所有行

[root@server2 ~]# nl test.txt | sed '/home/!d'    
3	The home of Football on BBC Sport online.

刪除以a-z小寫字母為開頭的內容

[root@server2 ~]#  sed '/^[a-z]/d' test.txt 

在這裡插入圖片描述

刪除以.為結尾的內容

[root@server2 ~]#  sed '/\.$/d' test.txt 

在這裡插入圖片描述

刪除所有空行

[root@server2 ~]# vi test.txt 
[root@server2 ~]#  sed '/^$/d' test.txt 

在這裡插入圖片描述

替換內容

將每行中的第一個the替換為THE

[root@server2 ~]# sed 's/the/THE/' test.txt 

在這裡插入圖片描述
在這裡插入圖片描述

將檔案中的所有the替換為THE

[root@server2 ~]# sed 's/the/THE/g' test.txt 

在這裡插入圖片描述

將每行中的第2個l替換為L

[root@server2 ~]# sed 's/l/L/2' test.txt 

在這裡插入圖片描述

將檔案中的所有的o刪除(替換為空串)

[root@server2 ~]# sed 's/o//g' test.txt 

在這裡插入圖片描述

在每行行首插入#號

[root@server2 ~]# sed 's/^/#/' test.txt 

在這裡插入圖片描述

在每行行尾插入字串EOF

[root@server2 ~]# sed 's/$/EOF/' test.txt 

在這裡插入圖片描述

在包含the的每行行首插入#號

[root@server2 ~]# sed '/the/s/^/#/' test.txt 

在這裡插入圖片描述

將包含the的所有行中的o替換為O

[root@server2 ~]# sed '/the/s/o/O/g' test.txt 

在這裡插入圖片描述

  • 注:H:複製到剪下板 g,
  • G :將剪下板中的資料覆蓋/追加至指定行
  • w:儲存為檔案
  • r:讀取指定檔案
  • a:追加指定內容

修改內容

將包含the的行遷移至檔案末尾,{;}用於多個操作

[root@server2 ~]# sed '/the/{H;d};$G' test.txt

在這裡插入圖片描述

將第1-4行內容轉移至第16行後

[root@server2 ~]# sed '1,4{H;d};16G' test.txt

在這裡插入圖片描述

將包含the的行另存為檔案out.file

[root@server2 ~]# sed '/the/w out.file' test.txt 
[root@server2 ~]# ls -lh
[root@server2 ~]# cat out.file 

在這裡插入圖片描述
在這裡插入圖片描述

將檔案/etc/hostname的內容新增到包含the的每行以後

[root@server2 ~]# sed '/the/r /etc/hostname' test.txt 

在這裡插入圖片描述

在第三行前面插入一個新行,內容為New

[root@server2 ~]# sed '3iNew' test.txt

在這裡插入圖片描述

在包含the的每行後插入一個新行,內容為New

[root@server2 ~]# sed '/the/aNew' test.txt 

在這裡插入圖片描述

在檔案最後結尾後插入一個新行,內容為New

[root@server2 ~]# sed '$aNew' test.txt 

在這裡插入圖片描述

在第三行後插入一個新行,內容為New1,後換行插入一個新行,內容為new2

(中間的\n表示換行)

[root@server2 ~]# sed '4aNew1\nnew2' test.txt 

在這裡插入圖片描述

  • 注意:\n 和\r的區別:
    \n 換行符,是另起一新行(遊標換行)
    \r 回車符,遊標回到一舊行的開頭(覆蓋前一個)

使用指令碼編輯檔案

使用sed指令碼將多個編輯指令存放到檔案中執行

[root@server2 ~]# vi opt.list
1,5H   15行剪下
1,5d   15行刪除
17G     17行追加
[root@server2 ~]# sed -f opt.list test.txt 

在這裡插入圖片描述

sed直接操作檔案範例

編寫一個指令碼,用來調整vsftpd 服務設定,要求禁止匿名使用者,但允許本地使用者

[root@server2 ~]# useradd dada
[root@server2 ~]# passwd dada
[root@server2 ~]# useradd xiaoxiao
[root@server2 ~]# passwd xiaoxiao
[root@server2 ~]# vi ftp.sh
#!/bin/bash
A=vsftpd
FTP=/etc/vsftpd/vsftpd.conf
yum -y install $A
sed -i -e '/local_enable/s/NO/YES/g' $FTP
sed -i -e '/write_enable/s/NO/YES/g' $FTP
sed -i -e 's/^#chroot_local_user=YES/chroot_local_user=YES/g' $FTP
sed -i  '$aallow_writeable_chroot=YES' $FTP
sed -i -e '/listen/s/NO/YES/g' $FTP
sed -i -e '/listen_ipv6/s/YES/NO/g' $FTP
systemctl start $A
netstat -anpt | grep $A
[root@server2 ~]# chmod +x ftp.sh
[root@server2 ~]# ./ftp.sh

在這裡插入圖片描述
客戶機上安裝ftp進行存取

[root@server1 ~]# yum -y install ftp
[root@server1 ~]# ftp 20.0.0.11
Name (20.0.0.11:root): dada
ftp> exit
[root@server1 ~]# ftp 20.0.0.11
Name (20.0.0.11:root): xiaoxiao
ftp> exit

在這裡插入圖片描述
驗證成功