Shell正則四劍客 | sed命令

sed簡介

        sed 是一種在線編輯器,它一次處理一行內容。處理時,把當前處理的行存儲在臨時緩衝區中,稱爲「模式空間」(pattern space),接着用sed命令處理緩衝區中的內容,處理完成後,把緩衝區的內容送往屏幕。接着處理下一行,這樣不斷重複,直到文件末尾。文件內容並無 改變,sed只是對緩衝區中原始文件的副本進行編輯,並非編輯原始的文件。除非你使用重定向存儲輸出或者使用使用sed編輯命令中的w選項。Sed主要用來自動編輯一個或多個文件;簡化對文件的反覆操做。html

       SED是一個非交互式文本編輯器,它可對文本文件和標準輸入進行編輯,標準輸入能夠來自鍵盤輸入、文本重定向、字符串、變量,甚至來自於管道的文本,與VIM編輯器相似,它一次處理一行內容,Sed能夠編輯一個或多個文件,簡化對文件的反覆操做、編寫轉換程序等。linux

        在處理文本時把當前處理的行存儲在臨時緩衝區中,稱爲「模式空間」(pattern space),緊接着用SED命令處理緩衝區中的內容,處理完成後把緩衝區的內容輸出至屏幕或者寫入文件。正則表達式

        逐行處理直到文件末尾,然而若是打印在屏幕上,實質文件內容並無改變,除非你使用重定向存儲輸出或者寫入文件。其語法參數格式爲:shell

sed [-Options] [‘Commands’] filename;bash

sed工具默認處理文本,文本內容輸出屏幕已經修改,可是文件內容其實沒有修改,須要加-i參數即對文件完全修改;

sed命令參數

  • a :新增, a 的後面能夠接字串,而這些字串會在新的一行出現(目前的下一行)
  • c :取代, c 的後面能夠接字串,這些字串能夠取代 n1,n2 之間的行!
  • d :刪除,由於是刪除啊,因此 d 後面一般不接任何咚咚;
  • i :插入, i 的後面能夠接字串,而這些字串會在新的一行出現(目前的上一行);
  • p :列印,亦即將某個選擇的數據印出。一般 p 會與參數 sed -n 一塊兒運行
  • s :取代,能夠直接進行取代的工做哩!一般這個 s 的動做能夠搭配正規表示法!例如 1,20s/old/new/g 就是啦

x             #x爲指定行號;編輯器

x,y              #指定從x到y的行號範圍;工具

/pattern/              #查詢包含模式的行;ui

/pattern/pattern/              #查詢包含兩個模式的行;this

/pattern/,x              #從與pattern的匹配行到x號行之間的行;spa

x,/pattern/              #從x號行到與pattern的匹配行之間的行;

x,y!                          #查詢不包括x和y行號的行;

r                 #從另外一個文件中讀文件;

w              #將文本寫入到一個文件;

y              #變換字符;

q              #第一個模式匹配完成後退出;

l                #顯示與八進制ASCII碼等價的控制字符;

 

元字符集

^:              匹配一行的開始

$:              匹配一行的結束

.:               匹配某個字符

[abc]:        匹配指定範圍字符

 

sed命令基本用法

sed : Stream EDitor 行編輯器 (全屏編輯器 : vi)

sed : 模式空間 默認不編輯原文件,僅對模式空間中的數據作處理 : 然後,處理結束後,將模式空間打印至屏幕: sed 'AddressCommand' file ...

Address(地址) 指定方法: 一、StartLin(起始行),EndLine(結束行) 好比 :1,100 $ :最後一行 二、/RegExp/(正則表達式指定的模式) /^root/ 三、/pattern1/,/pattern2/ 第一次被pattern1匹配到的行開始,至第一次被pattern2匹配到的行結束,這中間的全部行 四、LineNumber 五、StartLine(起始行), +N 從StartLine開始,向後的N行:

命令格式

sed [options] '{command}' [filename]
sed [options] -f scriptfile [filename]

選項

經常使用選項 選項說明
sed -n 抑制自動輸出;靜默模式,再也不默認顯示模式空間中的內容
sed -e SCRIPT -e SCRIPT 添加腳本 ;能夠同時執行多個腳本
sed -f /PATH/TO/SED_SCRIPT 添加腳本文件
sed -f /PATH/TO/SED_SCRIPT file

| sed -i | 編輯文件內容;直接修改源文件 | | sed -i.bak | 修改文件同時建立.bak備份文件 | | sed -r | 使用擴展的正則表達式;將指定的文件的內容添加至符合條件的行處 |

經常使用命令參數 參數說明
a \「string」 在匹配後面添加新的行,內容爲「string」
案例:一、sed '/^\//a \# hello word' /etc/fstab    #在/etc/fstab後面,添加hello word。
  二、sed '/^\//a \# hello word\n#hello,linux' /etc/fstab         #在/etc/fstab後面,添加hello word和hello,Linux。

| d | 刪除符合條件的行 | 案例 :一、sed '1,2d' /etc/fstab #刪除/etc/fstab 中的第1,2行 二、sed '1,$-1d' /etc/fstab #刪除/etc/fstab 中的第1到到數第二行 三、sed '3,$d' /etc/fstab #刪除/etc/fstab 中的31到最後1行 | i \string | 在匹配前面添加新行,內容爲string | \n:能夠用於換行 | s | 查找替換,默認只替換每行中第一行被模式匹配到的字符 | 加修飾符 g:全局替換 i:忽略字符大小寫 案例 :一、 sed 's/oot/OOT' /etc/fstab #在/etc/fstab中的oot替換成OOT 二、 sed 's/^//#/' /etc/fstab #在/etc/fstab中的行首的/替換成# 三、 sed 's///#/' /etc/fstab #在/etc/fstab中的所有的/替換成# | p | 打印 / 顯示符合條件的行|    案例 : sed '/^//p' /etc/fstab #顯示/etc/fstab下,以/開頭的行 | y FILE| 轉換 |

| w FILE| 將地址指定範圍內的行另存至指定的文件中 | | h H | 拷貝/添加模式空間到存放空間 | | g G | 拷貝/添加存放空間到模式空間 |

sed -i.bak '/^\s*#/d;/^$/d' <filename>

詳細介紹一下上面的腳本:

  • sed -i.bak:sed 命令會建立一個以.bak結尾的備份文件,用來備份原始的文件。
  • /^:表示行首。
  • \s*:匹配任何不可見字符,包括空格、製表符、換頁符等。
  • #/:shell 腳本中的註釋標記。/^\s*#/一塊兒使用用來查找註釋行和帶有不可見字符的註釋行。
  • d:用來刪除匹配的行。
  • ;/^$/d;是表達式的分隔符,後面的表達式跟前面的表達式意思很像,用來刪除空白行, "$"匹配輸入字符串的結束位置。

 

指令參數

a\    當前行下面插入文本。
i\    在當前行上面插入文本。
c\    把選定的行改成新的文本。

d    刪除,刪除選擇的行。
D    刪除模板塊的第一行。
s    替換指定字符
h    拷貝模板塊的內容到內存中的緩衝區。
H    追加模板塊的內容到內存中的緩衝區。
g    得到內存緩衝區的內容,並替代當前模板塊中的文本。
G    得到內存緩衝區的內容,並追加到當前模板塊文本的後面。
l    列表不能打印字符的清單。
n    讀取下一個輸入行,用下一個命令處理新的行而不是用第一個命令。
N    追加下一個輸入行到模板塊後面並在兩者間嵌入一個新行,改變當前行號碼。
  1. N             追加下一個輸入行到模板塊後面並在兩者間嵌入一個新行,改變當前行號碼。

  2. p             打印模板塊的行。

  3. P             (大寫) 打印模板塊的第一行

  4. ^             行的開始

  5. $             行的結尾

  6. .             一個字符

  7. *             0個或多個前一個字符

  8. []            方括號中的全部字符

  9. {}             重複次數

  10. ()             組

  11. /./            匹配至少有一個字符的行

  12. /../           匹配至少有兩個字符的行

  13. /^#/           匹配用#開頭的行

  14. /^$/           匹配空行

  15. /}$/           匹配用}結尾的行(沒有空格在後面)

  16. /} *$/         匹配用}結尾的行(能夠有空格在後面)

  17. /[abc]/        匹配小寫的a或b或c

  18. /^<a href="#footnote-abc"><sup>[abc]</sup></a>/                匹配開頭不是小寫的a或b或c

      一般而言,SED將待處理的行讀入模式空間,腳本中的命令逐行進行處理,直到腳本執行完畢,而後該行被輸出,模式空間請空;而後重複剛纔的動做,文件中的新的一行被讀入,直到文件處理完備。 

       若是用戶但願在某個條件下腳本中的某個命令被執行,或者但願模式空間獲得保留以便下一次的處理,都有可能使得sed在處理文件的時候不按照正常的流程來進行。這時可使用SED高級語法來知足用戶需求。總的來講,SED高級命令能夠分爲三種功能:

  • N、D、P:處理多行模式空間的問題;

  • H、h、G、g、x:將模式空間的內容放入存儲空間以便接下來的編輯;

  • :、b、t:在腳本中實現分支與條件結構。

 

一、在jfedu.txt每行後加入空行,也即每行佔永兩行空間,每一行後邊插入一行空行、兩行空行及前三行每行後插入空行:

sed ‘/^$/d;G’ jfedu.txt

sed ‘/^$/d;G;G’ jfedu.txt

sed ‘/^$/d;1,3G;’ jfedu.txt

 

二、將jfedu.txt偶數行刪除及隔兩行刪除一行:

sed ‘n;d’ jfedu.txt

sed ‘n;n;d’ jfedu.txt

 

三、在jfedu.txt匹配行前一行、後一行插入空行以及同時在匹配先後插入空行:

sed ‘/jfedu/{x;p;x;}’ jfedu.txt

sed ‘/jfedu/G’ jfedu.txt

sed ‘/jfedu/{x;p;x;G;}’ jfedu.txt

 

四、在jfedu.txt每行後加入空行,也即每行佔永兩行空間,每一行後邊插入空行:

sed ‘/^$/d;G’ jfedu.txt

 

五、在jfedu.txt每行後加入空行,也即每行佔永兩行空間,每一行後邊插入空行:

sed ‘/^$/d;G’ jfedu.txt

 

六、在jfedu.txt每行前加入順序數字序號、加上製表符\t及.符號:

sed = jfedu.txt| sed ‘N;s/\n/ /’

sed = jfedu.txt| sed ‘N;s/\n/\t/’

sed = jfedu.txt| sed ‘N;s/\n/\./’

 

七、刪除jfedu.txt行前和行尾的任意空格:

sed ‘s/^[ \t]*//;s/[ \t]*$//’ jfedu.txt

 

八、打印jfedu.txt關鍵詞old與new之間的內容:

sed -n ‘/old/,/new/’p jfedu.txt

 

九、打印及刪除jfedu.txt最後兩行:

sed ‘$!N;$!D’ jfedu.txt

sed ‘N;$!P;$!D;$d’ jfedu.txt

 

十、合併上下兩行,也即兩行合併:

sed ‘$!N;s/\n/ /’ jfedu.txt

sed ‘N;s/\n/ /’ jfedu.txt

 

sed命令小練習

打印操做:p命令

1. sed -n '5'p /etc/passwd

2. sed -n '1,5'p /etc/passwd

3. sed -n '1,$'p /etc/passwd

4. sed -n '/root/'p /etc/passwd

5. sed -n '/^1/'p /etc/passwd

6. sed -n 'in$'p /etc/passwd

7. sed -n '/r..o/'p /etc/passwd

8. sed -n 'oo*'p /etc/passwd

9. sed -e '1'p -e /111/'p -n /etc/passwd

十、sed -n '+5'p /etc/passwd

 

十一、sed '2r /etc/issue' /etc/fstab                          #在/etc/fstab第二行添加etc/issue

十二、sed '$r /etc/issue' /etc/fstab                          #在/etc/fstab第後面行添加etc/issue

1三、sed '1,2r /etc/issue' /etc/fstab                     #在/etc/fstab第一,二行添加etc/issue

sed -n '1,3p'                                             #打印出file1文件第一到第三行

sed -e 's/jk$/yz/g' test.txt                                           #修改文本中以jk結尾的替換成

sed ‘s/old/new/g’ jfedu.txt                                  #替換jfedu.txt文本中old爲new

sed -n ‘1,3p’ jfedu.txt                                    # 打印jfedu.txt文本第一行至第三行

sed -n ‘1p;$p’ jfedu.txt                                #打印jfedu.txt文本中第一行與最後一行:

sed ‘1,3d’ jfedu.txt

sed ‘/jfedu/,$d’ jfedu.txt                                    #刪除jfedu.txt第一行至第三行、刪除匹配行至最後一行:

for i in `seq 1 6`;do sed -i ‘$d’ jfedu.txt ;done                               

sed ‘$d’ jfedu.txt                                                                            #刪除jfedu.txt最後6行及刪除最後一行                    

sed ‘$d’ jfedu.txt                                                      #刪除jfedu.txt最後一行

 

打印最後一行
[root@localhost ~]# sed -n '$ p' jfedu.net

打印匹配對應字符行
[root@localhost ~]# sed -n '/baidu/ p' jfedu.net

打印從第一行到匹配行
[root@localhost ~]# sed -n '1,/jf/ p' jfedu.net

以匹配條件做爲匹配實例
[root@localhost ~]# sed -n '/jfedu/,/jf/ p'

 

在匹配文本的上一行或者是下一行增長行
[root@localhost ~]# sed '/baidu/ a www.baidu1.com'

在匹配行的下一行增長參數
[root@localhost ~]# sed '/baidu/ i www.baidu1.com'

 

追加字符
[root@localhost ~]# sed 's/com$/ test &/g' jfedu.net

[root@localhost ~]# sed 's/com$/ & test/g' jfedu.net

 

修改一下示例文件:
sed -i
's/^www/https:\/\/&/g;s/com$/&\/index.html/;s/net$/&\/
index.html/' jfedu.net

 

修改示例文件,單獨取出域名
#示例awk
[root@localhost ~]# awk -F"/" '{print $3}' jfedu.net

 

1四、刪除/etc/grub.conf文件中行首的空白符                 sed -r 's@^[[:spapce:]]+@@g' /etc/grub.conf

1五、替換/etc/inittab文件中"id:3:initdefault:"一行中的數字爲5;              sed 's@(id:)[0-9](:initdefault:)@\15\2@g' /etc/inittab

1六、刪除/etc/inittab文件中空白行;                            sed '/^$/d' /etc/inittab

1七、刪除/etc/inittab文件中開頭的#號                         sed 's@^@@g' /etc/inittab

1八、刪除某文件中之後面的空白字符,但要求#號後面必須有空白字符;                     

sed -r 'S@^[[!space:]]+#@@g' /etc/inittab

1九、刪除某文件中以空白字符後面跟#類的行中的開頭的空白字符                                 # sed -r 's@^[[!space:]]+#@@g' /etc/inittab

20、取出一個文件路徑的目錄名稱; echo "/etc/rc.d/" sed -r 's@^(/.*/)[^/]+/7@\1@g'

2一、傳遞一個參數(單字符就行)給腳本,如參數爲q,Q,quit,或Quit,就退出腳本不然,就顯示用戶的參數:

#!/bin/bash

if [ $1 = 'q' ];then echo "Quiting..."

   elif [ $1 = 'Q' ];

      then echo "Quiting..." exit 2 elif [ $1 = 'quit' ];

       then echo "Quiting..." exit 4 else echo $1

fi

 

2二、統計一共有多少個用戶

for I in 'seq 1 $LINES'; do echo "Hello, 'head -n $I /etc/passwd | tail -l | cut -d:-f1'";done 只向默認shell爲bash的用戶問聲好

2三、添加10個用戶user1到user10,密碼同用戶名,但要求只有用戶不存在的狀況下才能添加。 擴展 : 接受一個參數: add : 添加用戶user1..user10 del :刪除用戶user1..user10 其餘:退出

#!/bin/bash

for I in (1..10); do if id user$I &>/dev/null; then echo 'user$I' exists. else useradd user$I echo user$I | passwd --stdin user$I &> /dev/null echo "Add user user$I finished." fi done

#!/bin/bash

for I in (1..10); do if id user$I &>/dev/null; then userdell -r user$I echo 'Delete user$I' fineshed. else echo "user$I not exist." fi done

2四、查找/var目錄下屬主爲root而且屬組爲mail的全部文件:

find /var -user root -group mial

 

2五、查找/usr目錄下不屬於root,bin,或student的文件: find /usr -not -user root -a -not -user bin -a -not -user student find /usr -not ( -user root -o -user bin -o -user student )

2六、查找/etc目錄下最近一週內內容修改且不屬於root及student用戶的文件: find /etc -mtime -7 -not \ ( -user root -o -user student ) find /etc/ -mtime -7 -not -user root -a -not -user student

 

2七、查找當前系統上沒有屬主或屬組且最近1天內曾被訪問過的文件,並將其屬主屬組均修改成root: find / \( -nouser -o nogroup \) -a -atime -1 -exec chown root:root () ;

2八、查找/etc目錄下大於1M的文件,並將其文件寫入/tmp/etc.largefiles文件中:                 find /etc/ -size -1M >> /tmp/etc.largefiles

 

2九、查找/etc目錄下全部用戶都沒有寫權限的文件,顯示出其詳細信息;                                 find /etc -not -perm /222 -ls

30、查找/etc目錄下大於1M的文件,並追加到/tmp/etc.largefiels

find /etc -szie +1M -exec echo {} >> /tmp/etc.largefile ; find /etc -szie +1M xarges echo {} >> /tmp/etc.largefile

 

3一、命令:a\

在匹配行的後面加入一行文本

示例(4)匹配100的行,後面加入一行"new line"

sed '/100/'a\ "new line" hello.txt

輸出內容爲:

1 2 3

10 20 30

100 200 300

new line

命令:i\

在匹配行的前面加入一行文本

示例(5)匹配100的行,前面加入一行"new line"

sed '/100/'i\ "new line" hello.txt

輸出內容爲:

1 2 3

10 20 30

new line

100 200 300

 

命令:c\

將匹配行替換爲目的行

示例(5)匹配100的行,替換爲"new line"

sed '/100/'c\ "new line" hello.txt

輸出內容爲:

1 2 3

10 20 30

new line

 

命令:d

將匹配行刪除

示例(5)刪除匹配100的行

sed '/100/'d hello.txt

輸出內容爲:

1 2 3

10 20 30

 

命令:s

將匹配行替換

詳細命令爲:s/pattern-to-find/replacement-pattern/g

pattern-to-find:被替換的串

replacement-pattern:替換成這個串

g:所有替換,默認只替換匹配到的第一個

示例(5)講100替換爲hello

sed 's/100/hello/g' hello.txt

輸出內容爲:

1 2 3

10 20 30

hello 200 300

 

匹配以10開頭的行,並替換爲yes,並輸出

sed -n 's/^10/yes/p' hello.txt

輸出內容爲:

yes 20 30

yes0 200 300

 

取出文件中行手的行號與冒號

設hello.txt的內容爲

1:#!/bin/sh

2:cat hello.txt

3:exit

 

sed -n -e 's/^[0-9]\{1,\}://g'p hello.txt

輸出結果爲:

#!/bin/sh

cat hello.txt

exit

 

3二、

3三、

3四、

3五、

3六、

3七、

3八、

3九、

40、

刪除操做:d命令

  1. ## 刪除 第1行

  2. sed '1'd /etc/passwd

  3. sed '1d' /etc/passwd

  4. ## 刪除 第1行 和 第3行

  5. sed '1,3'd /etc/passwd

  6. ## 刪除包含 字符串oot的行

  7. sed '/oot/'d /etc/passwd

  8. ## 刪除空白行

  9. sed '/^$/d' /etc/passwd

  10. ## 刪除文件最後一行

  11. sed '$d' /etc/passwd

十二、sed '1,+2d' /etc/fstab #刪除第一行和向後的兩行

1三、

替換文件內容

  1. sed 's/[0-9]//g' /etc/passwd

  2. sed s/[a-zA-Z]//g' /etc/passwd

  3. sed 's#ot#to#g' /etc/passwd

追加(行下追加):a\

  1. ## 行下追加

  2. [root@ansible-master awk]# head -2 text | sed '/^root/a\this is a test line'

  3. root:x:0:0:root:/root:/bin/bash

  4. this is a test line

  5. rootaaaaa:x:10:0:root:/root:/bin/bash

  6. this is a test line

  7. ## 指定行下追加

  8. [root@ansible-master awk]# head -3 text | sed '2a\this is a test line'

  9. root:x:0:0:root:/root:/bin/bash

  10. rootaaaaa:x:10:0:root:/root:/bin/bash

  11. this is a test line

追加(行下追加):a\

  1. ## 指定行上追加

  2. [root@ansible-master awk]# head -3 text | sed '2i\this is a test line'

  3. root:x:0:0:root:/root:/bin/bash

  4. this is a test line

  5. rootaaaaa:x:10:0:root:/root:/bin/bash

  6. ## 匹配行上追加

  7. [root@ansible-master awk]# head -5 text | sed '/^root/i\this is a test line'

  8. this is a test line

  9. root:x:0:0:root:/root:/bin/bash

  10. this is a test line

  11. rootaaaaa:x:10:0:root:/root:/bin/bash

互換

  1. ## 匹配並替換,將第1字段 和 第7字段進行互換

  2. [root@ansible-master awk]# sed -r 's/([^:]+):(.*):([^:]+)/\3:\2:\1/' /etc/passwd

  3. /bin/bash:x:0:0:root:/root:root

  4. /sbin/nologin:x:1:1:bin:/bin:bin

  5. /sbin/nologin:x:2:2:daemon:/sbin:daemon

  6. /sbin/nologin:x:3:4:adm:/var/adm:adm

  7. ## 在行首添加字符串 aaa

  8. [root@ansible-master awk]# sed -r 's/(.*)/aaa:&/' /etc/passwd

  9. aaa:root:x:0:0:root:/root:/bin/bash

  10. aaa:bin:x:1:1:bin:/bin:/sbin/nologin

  11. aaa:daemon:x:2:2:daemon:/sbin:/sbin/nologin

 

參考連接 : https://mp.weixin.qq.com/s/P6iB1xw8rFtjbwkSPlouQQ

SHELL——文本處理(三):sed關於 p、d、a、c、i 模式 : https://blog.csdn.net/qq_42036824/article/details/85225654

相關文章
相關標籤/搜索