自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Linux基礎(chǔ)命令介紹十:文本流編輯 sed

系統(tǒng) Linux
sed的工作過程是這樣的:首先,初始化兩個數(shù)據(jù)緩沖區(qū)模式空間和保持空間;sed讀取一行輸入(來自標(biāo)準(zhǔn)輸入或文件),去掉結(jié)尾的換行符(\n)后置于模式空間中,然后針對模式空間中的字符串開始執(zhí)行‘sed命令’,每個命令都可以有地址與之相關(guān)聯(lián),地址可以看成是條件,只有在條件成立時,相關(guān)的命令才被執(zhí)行;所有可執(zhí)行命令都處理完畢后,仍處于模式空間中的字符串會被追加一個換行符后打印輸出;之后讀取下一行輸入做同樣的處理,直到主動退出(q)或輸入結(jié)束。

[[179651]]

與vim不同,sed是一種非交互式的文本編輯器,同時它又是面向字符流的,每行數(shù)據(jù)經(jīng)過sed處理后輸出。 

  1. sed [OPTION]... [script] [file]... 

sed的工作過程是這樣的:首先,初始化兩個數(shù)據(jù)緩沖區(qū)模式空間和保持空間;sed讀取一行輸入(來自標(biāo)準(zhǔn)輸入或文件),去掉結(jié)尾的換行符(\n)后置于模式空間中,然后針對模式空間中的字符串開始執(zhí)行‘sed命令’,每個命令都可以有地址與之相關(guān)聯(lián),地址可以看成是條件,只有在條件成立時,相關(guān)的命令才被執(zhí)行;所有可執(zhí)行命令都處理完畢后,仍處于模式空間中的字符串會被追加一個換行符后打印輸出;之后讀取下一行輸入做同樣的處理,直到主動退出(q)或輸入結(jié)束。

地址

地址可以是如下的形式

1、number 表示行號

2、first~step 表示從first(數(shù)字)行開始,每隔step(數(shù)字)行

3、$ 表示***一行(注意當(dāng)出現(xiàn)在正則表達(dá)式中時表示行尾)

4、/regexp/ 表示匹配正則表達(dá)式regexp(關(guān)于正則表達(dá)式,請參見這一篇)

5、\%regexp% 表示匹配正則表達(dá)式regexp,%可以換成任意其他單個字符。(用于regexp包含斜線/的情況)

6、/regexp/I 匹配正則表達(dá)式regexp時不區(qū)分大小寫

7、/regexp/M 啟用正則多行模式,使$不止匹配行尾,還匹配n或r之前的位置;使^不止匹配行首,還匹配n或r之后的位置。此時可以用(\`)匹配模式空間的開頭位置,用(\')匹配模式空間的結(jié)束位置。

還可以用逗號,分隔兩個地址來表示一個范圍

表示從匹配***個地址開始,直到匹配第二個地址或文件結(jié)尾為止。如果第二個地址是個正則表達(dá)式,則不會對***個地址匹配行進(jìn)行第二個地址的匹配;如果第二個地址是行號,但小于或等于***個地址匹配行行號,則只會匹配一行(***個地址匹配行)。

8、0,/regexp/ 這種情況下,正則表達(dá)式regexp會在***行就開始進(jìn)行匹配。只有第二個地址是正則表達(dá)式時,***個地址才能用0。

9、addr1,+n表示匹配地址addr1和其后的n行。

10、addr1,~n表示從匹配地址addr1開始,直到n的倍數(shù)行為止。

如果沒有給出地址,所有的行都會匹配;在地址或地址范圍后追加字符!表示對地址取反,所有不匹配的行才會被處理。

選項(xiàng)

-n 默認(rèn)時每一行處理過的字符串都會被打印輸出,此選項(xiàng)表示關(guān)閉此默認(rèn)行為。只有被命令p作用的字符串才會被輸出。

-f file表示從file中讀取sed命令

-i 表示原地修改。應(yīng)用此選項(xiàng)時,sed會創(chuàng)建一個臨時文件,并將處理結(jié)果輸出到此文件,處理完畢后,會將此臨時文件覆蓋至原文件。

-r 表示使用擴(kuò)展的正則表達(dá)式

命令

p表示打印模式空間內(nèi)容,通常配合選項(xiàng)-n一起使用

  1. [root@centos7 ~]# seq 5 
  2. [root@centos7 ~]# 只輸出第二行到第四行 
  3. [root@centos7 ~]# seq 5|sed -n '2,4p' 
  4. [root@centos7 ~]#   

d 刪除模式空間內(nèi)容,立即處理下一行輸入。

  1. #刪除***一行 
  2. [root@centos7 ~]# seq 5|sed '$d' 
  3. [root@centos7 ~]#  

q 立即退出,不再處理任何命令和輸入(只接受單個地址)

  1. [root@centos7 ~]# seq 5|sed '/3/q' 
  2. [root@centos7 ~]#  

n 如果沒有使用選項(xiàng)-n,輸出模式空間中內(nèi)容后,讀取下一行輸入并覆蓋當(dāng)前模式空間內(nèi)容。如果沒有更多的輸入行,sed會退出執(zhí)行。

  1. [root@centos7 ~]# seq 9|sed -n 'n;p' 
  2. [root@centos7 ~]# 注意多個命令用分號分隔  

s/regexp/replacement/flag 表示用replacement替換模式空間中匹配正則表達(dá)式regexp的部分。在這里符號/可以換成任意單個字符。 

  1. [root@centos7 ~]# echo "hello123world"|sed 's/[0-9]\+/,/'   
  2. hello,world 
  3. #注意這里+需要轉(zhuǎn)義,如果使用選項(xiàng)-r則無需轉(zhuǎn)義  

在replacement中

1、\n (n為1-9中的一個數(shù)字)表示對正則表達(dá)式中分組(...)的引用;

  1. [root@centos7 ~]# echo "hello123world"|sed -r 's/[a-z]+([0-9]+)[a-z]+/\1/' 
  2. 123 
  3. [root@centos7 ~]# echo "hello123world"|sed -r 's/([a-z]+)[0-9]+([a-z]+)/\1,\2/' 
  4. hello,world  

2、&表示模式空間中所有匹配regexp的部分;

  1. [root@centos7 ~]# echo "hello123world"|sed -r 's/[0-9]+/:&:/' 
  2. hello:123:world  

3、\L 將后面的字符轉(zhuǎn)化成小寫直到 \U 或 \E 出現(xiàn);

4、\l 將下一個字符轉(zhuǎn)化為小寫;

5、\U 將后面的字符轉(zhuǎn)化成大寫直到 \L 或 \E 出現(xiàn);

6、\u 將下一個字符轉(zhuǎn)化為大寫;

7、\E 停止由 \L 或 \U 起始的大小寫轉(zhuǎn)化;

  1. [root@centos7 ~]# echo "hello123world"|sed -r 's/^([a-z]+)[0-9]+([a-z]+)$/\U\1\E,\u\2/' 
  2. HELLO,World 
  3. [root@centos7 ~]#   

flag

1、n數(shù)字n表示替換第n個匹配項(xiàng)

  1. [root@centos7 ~]# head -1 /etc/passwd 
  2. root:x:0:0:root:/root:/bin/bash 
  3. #替換冒號分隔的第五部分為空 
  4. [root@centos7 ~]# head -1 /etc/passwd|sed 's/[^:]\+://5' 
  5. root:x:0:0:/root:/bin/bash  

2、g表示全局替換

  1. [root@centos7 ~]# echo "hello123world"|sed 's/./\U&\E/' 
  2. Hello123world 
  3. [root@centos7 ~]#  
  4. [root@centos7 ~]# echo "hello123world"|sed 's/./\U&\E/g' 
  5. HELLO123WORLD 
  6. [root@centos7 ~]# 
  7. #當(dāng)數(shù)字n和g同時使用時,表示從第n個匹配項(xiàng)開始替換一直到***匹配項(xiàng) 
  8. [root@centos7 ~]# head -1 /etc/passwd|sed 's/[^:]\+://4g' 
  9. root:x:0:/bin/bash/  

3、p表示如果替換成功,則打印模式空間內(nèi)容。

4、w file表示如果替換成功,則輸出模式空間內(nèi)容至文件file中。

5、I和i表示匹配regexp時不區(qū)分大小寫。

  1. [root@centos7 ~]# echo 'HELLO123world'|sed -r 's/[a-z]+//Ig' 
  2. 123 
  3. [root@centos7 ~]#  

6、M和m表示啟用正則多行模式(如前所述)。(講命令N時再舉例)

  1. [root@centos7 ~]# echo hello|sed 'y/el/LE/'       
  2. hLEEo 
  3. [root@centos7 ~]#  

a text表示輸出模式空間內(nèi)容后追加輸出text內(nèi)容

  1. [root@centos7 ~]# seq 3|sed '1,2a hello'  
  2. hello 
  3. hello 
  4. [root@centos7 ~]#  

i text表示輸出模式空間內(nèi)容之前,先輸出text內(nèi)容

  1. [root@centos7 ~]# seq 3|sed '$ihello' 
  2. hello 
  3. [root@centos7 ~]#   

c text表示刪除匹配地址或地址范圍的模式空間內(nèi)容,輸出text內(nèi)容。如果是單地址,則每個匹配行都輸出,如果是地址范圍,則只輸出一次。

  1. [root@centos7 ~]# seq 5|sed '1,3chello' 
  2. hello 
  3. [root@centos7 ~]# seq 5|sed '/^[^3-4]/c hello'  
  4. hello 
  5. hello 
  6. hello  

=表示打印當(dāng)前輸入行行號

  1. [root@centos7 ~]# seq 100|sed -n '$=' 
  2. 100 
  3. [root@centos7 ~]# seq 100|sed -n '/^10\|^20/=' 
  4. 10 
  5. 20 
  6. 100 
  7. [root@centos7 ~]# 轉(zhuǎn)義的|表示邏輯或  

r file表示讀取file的內(nèi)容,并在當(dāng)前模式空間內(nèi)容輸出之后輸出

  1. [root@centos7 ~]# cat file  
  2. hello world 
  3. [root@centos7 ~]# seq 3|sed '1,2r file' 
  4. hello world 
  5. hello world 
  6. [root@centos7 ~]#   

w file表示輸出模式空間內(nèi)容至file中

N讀入一行內(nèi)容至模式空間后,再追加下一行內(nèi)容至模式空間(此時模式空間中內(nèi)容形如 line1\nline2 ),如果不存在下一行,sed會退出。

  1. [root@centos7 ~]# seq 10|sed -n 'N;s/\n/ /p' 
  2. 1 2 
  3. 3 4 
  4. 5 6 
  5. 7 8 
  6. 9 10 
  7. [root@centos7 ~]# 
  8. #s命令的m flag舉例 
  9. [root@centos7 ~]# seq 3|sed 'N;s/^2/xxx/'  
  10. [root@centos7 ~]# seq 3|sed 'N;s/^2/xxx/m'     
  11. xxx 
  12. [root@centos7 ~]# seq 3|sed 'N;s/1$/xxx/'  
  13. [root@centos7 ~]# seq 3|sed 'N;s/1$/xxx/M' 
  14. xxx 
  15.  

D如果模式空間中沒有新行(如命令N產(chǎn)生的新行),則和命令d起同樣作用;如果包含新行,則會刪除***行內(nèi)容,然后對模式空間中剩余內(nèi)容重新開始一輪處理。(注意:D后面的命令將會被忽略)

  1. [root@centos7 ~]# seq 5|sed 'N;D'   
  2. [root@centos7 ~]# seq 5|sed 'N;N;D'    
  3.  

P打印模式空間中***行內(nèi)容

  1. [root@centos7 ~]# seq 10|sed -n 'N;P'  
  2. [root@centos7 ~]# seq 10|sed -n 'N;N;P' 
  3. #注意另一種寫法輸出中的不同 
  4. [root@centos7 ~]# seq 10|sed -n '1~3P'  
  5. 10  

g用保持空間中的內(nèi)容替換模式空間中的內(nèi)容

  1. [root@centos7 ~]# seq 5|sed -n 'g;N;s/\n/xx/p' 
  2. xx2 
  3. xx4 
  4. [root@centos7 ~]#   

G追加一個換行符到模式空間,然后再將保持空間中的內(nèi)容追加至換行符之后。(此時模式空間中內(nèi)容形如 PATTERN\nHOLD )

  1. [root@centos7 ~]# seq 5|sed 'G;s/\n/xx/'   
  2. 1xx 
  3. 2xx 
  4. 3xx 
  5. 4xx 
  6. 5xx  

h用模式空間中的內(nèi)容替換保持空間中的內(nèi)容(注意此時模式空間中的內(nèi)容并沒有被清除)

  1. [root@centos7 ~]# seq 5|sed -n 'h;G;s/\n/xx/p' 
  2. 1xx1 
  3. 2xx2 
  4. 3xx3 
  5. 4xx4 
  6. 5xx5 
  7. [root@centos7 ~]# seq 5|sed -n 'h;G;G;s/\n/xx/gp' 
  8. 1xx1xx1 
  9. 2xx2xx2 
  10. 3xx3xx3 
  11. 4xx4xx4 
  12. 5xx5xx5  

H追加一個換行符到保持空間,然后再將模式空間中的內(nèi)容追加至換行符之后。(此時保持空間中內(nèi)容形如 HOLD\nPATTERN )

  1. [root@centos7 ~]# seq 3|sed -n 'H;G;s/\n/xx/gp' 
  2. 1xxxx1 
  3. 2xxxx1xx2 
  4. 3xxxx1xx2xx3 
  5. [root@centos7 ~]#   

x交換模式空間和保持空間的內(nèi)容

  1. [root@centos7 ~]# seq 9|sed -n '1!{x;N};s/\n//p' 
  2. 25 
  3. 47 
  4. 69 
  5. #處于{...}之中的是命令組  

: label為分支命令指定標(biāo)簽位置(不允許地址匹配)

b label無條件跳轉(zhuǎn)到label分支,如果省略了label,則跳轉(zhuǎn)到整條命令結(jié)尾(即開始下一次讀入) 

  1. #如刪除xml文件中注釋部分(<!--...-->之間的部分是注釋,可以多行) 
  2. sed '/<!--/{:a;/-->/!{N;ba};d}' server.xml 
  3. #表示匹配<!--開始,在匹配到-->之前一直執(zhí)行N,匹配到-->之后刪除模式空間中內(nèi)容 
  4. #如在nagios的配置文件中,有許多define host{...}的字段,如下所示: 
  5. define host{ 
  6. use windows-server 
  7. host_name serverA 
  8. hostgroups 060202 
  9. alias 060202 
  10. contact_groups yu 
  11. address 192.168.1.1 
  12. #現(xiàn)在需要刪除ip地址是192.168.1.1的段,可以這樣: 
  13. sed -i '/define host/{:a;N;/}/!ba;/192\.168\.1\.1/d}' file 
  14. #注意和前一個例子中的區(qū)別  

t label在一次輸入后有成功執(zhí)行的s替換命令才跳轉(zhuǎn)到label,如果省略了label,則跳轉(zhuǎn)到整條命令結(jié)尾(即開始下一次讀入)

  1. #如行列轉(zhuǎn)換 
  2. [root@centos7 ~]# seq 10|sed ':a;$!N;s/\n/,/;ta' 
  3. 1,2,3,4,5,6,7,8,9,10 
  4. [root@centos7 ~]# 
  5. #如將MAC地址78A35114F798改成帶冒號的格式78:A3:51:14:F7:98 
  6. [root@centos7 temp]# echo '78A35114F798'|sed -r ':a;s/\B\w{2}\b/:&/;ta' 
  7. 78:A3:51:14:F7:98 
  8. [root@centos7 temp]# 
  9. #這里\b表示匹配單詞邊界,\B表示匹配非單詞邊界的其他任意字符 
  10. #當(dāng)然也可以采用其他的方式實(shí)現(xiàn): 
  11. [root@centos7 temp]# echo '78A35114F798'|sed -r 's/..\B/&:/g' 
  12. 78:A3:51:14:F7:98 
  13. [root@centos7 temp]#  

T label在一次輸入后只要沒有替換命令被成功執(zhí)行就跳轉(zhuǎn)到label,如果省略了label,則跳轉(zhuǎn)到整條命令結(jié)尾(即開始下一次讀入)

z表示清除模式空間中內(nèi)容,和s/.*//起相同的作用,但更有效。

更多例子

1、刪除匹配行的上一行和下一行

  1. #例如輸入數(shù)據(jù)為命令seq 10的輸出(當(dāng)然也可以是任意其他文件內(nèi)容) 
  2. #要求刪除匹配5那一行的前一行和后一行 
  3. [root@centos7 temp]# seq 10|sed -n '$!N;/\n5/{s/.*\n//p;N;d};P;D' 
  4. 10  

2、合并奇偶數(shù)行

  1. #輸入數(shù)據(jù)為命令seq 11的輸出,要求分別將奇數(shù)和偶數(shù)分別放在同一行 
  2. #輸出***行`1 3 5 7 9 11`,第二行`2 4 6 8 10` 
  3. [root@centos7 ~]# seq 11|sed -nr '$!N;2!G;s/([^\n]+)\n((.+)\n)?(.+)\n(.+)/\4 \1\n\5 \3/;h;$p' 
  4. 1 3 5 7 9 11 
  5. 2 4 6 8 10  
  6. [root@centos7 ~]#   

3、合并多文件

  1. #文本a.txt的內(nèi)容: 
  2. 01 12510101 4001 
  3. 02 12310001 4002 
  4. 03 12550101 4003 
  5. 04 12610001 4004 
  6. 05 12810001 4005 
  7. 06 12310001 4006 
  8. 07 12710001 4007 
  9. 08 12310001 4008 
  10. 09 12810101 4009 
  11. 10 12510101 4010 
  12. 11 12310001 4011 
  13. 12 12610001 4012 
  14. 13 12310001 4013 
  15. #文本b.txt的內(nèi)容: 
  16. A 12410101 2006/02/15 2009/01/31 4002 
  17. B 12310001 2006/08/31 2008/08/29 4001 
  18. C 12610001 2008/05/23 2008/05/22 4002 
  19. D 12810001 1992/12/10 1993/06/30 4001 
  20. E 12660001 1992/05/11 1993/06/01 4005 
  21. #要求輸出a.txt內(nèi)容中第二列和b.txt中第二列相同的行,并追加b.txt中對應(yīng)的兩個日期列。 
  22. #形如:02 12310001 4002 2006/08/31 2008/08/29 
  23. sed -rn '/^[01]/ba;H;:a;G;s/^((..)( .*)( [^\n]+)).*\3(( [^ ]*){2}).*/\1\5/p' b.txt a.txt 
  24. #當(dāng)然如果使用awk來處理的話,解決思路更容易理解一些: 
  25. awk 'NR==FNR{a[$2]=$3FS$4;next}{if($2 in a)print $0,a[$2]}' b.txt a.txt  

為加深對sed各種命令特性的理解,請自行分析這三個例子。

各種命令的組合使用,再加上正則表達(dá)式的強(qiáng)大能力,使得sed可以處理所有能夠計(jì)算的問題。但由于代碼可讀性不強(qiáng),理解起來比較困難,通常使用sed作為一個文本編輯器,對文本做非交互的流式處理。理解上述各個命令的含義,熟練使用它們,就會發(fā)現(xiàn)sed的強(qiáng)大之處。

責(zé)任編輯:龐桂玉 來源: segmentfault
相關(guān)推薦

2016-11-15 15:50:22

linux基礎(chǔ)命令vim

2016-12-07 18:22:23

shelllinuxgrep

2016-12-23 10:56:34

linuxshellawk

2022-08-17 12:35:26

Linux sed編輯器

2021-01-07 11:00:59

Sed文本編輯器Linux

2016-12-08 22:26:28

2019-08-28 15:43:03

sed命令Linux

2024-10-28 16:42:04

Linux編輯器sed 命令

2016-12-27 19:10:38

Linux命令啟動流程

2016-12-29 11:13:30

shellbashlinux

2021-06-13 09:01:47

SedLinux命令

2016-12-27 19:29:14

Linux命令定時任務(wù)

2023-07-03 22:35:50

Linux命令

2016-12-23 12:46:41

Linux命令進(jìn)程與內(nèi)存

2009-07-31 17:38:47

linux vi命令詳linux vi命令屏幕文本編輯器

2016-12-14 19:24:41

2016-12-27 10:34:57

Linux命令軟件包管理

2019-09-12 08:32:40

Linuxsed命令語法

2021-09-21 15:28:33

LinuxSed智能引號

2016-08-22 11:01:47

Linux命令行文本編輯器
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號