如何理解Linux基礎(chǔ)命令中文本流編輯sed命令

如何理解Linux基礎(chǔ)命令中文本流編輯sed命令,針對這個(gè)問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡單易行的方法。

目前成都創(chuàng)新互聯(lián)已為上千余家的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)站空間、網(wǎng)站托管、服務(wù)器托管、企業(yè)網(wǎng)站設(shè)計(jì)、懷遠(yuǎn)網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。

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

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

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

地址

地址可以是如下的形式

1、number 表示行號

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

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

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

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

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

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

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

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

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

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

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

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

選項(xiàng)

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

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

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

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

命令

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

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

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

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

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

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

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

[root@centos7 ~]# seq 9|sed -n 'n;p' 2 4 6 8 [root@centos7 ~]# 注意多個(gè)命令用分號分隔

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

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

在replacement中

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

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

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

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

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

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

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

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

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

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

flag

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

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

2、g表示全局替換

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

更多例子

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

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

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

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

3、合并多文件

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

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

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

關(guān)于如何理解Linux基礎(chǔ)命令中文本流編輯sed命令問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識。

文章題目:如何理解Linux基礎(chǔ)命令中文本流編輯sed命令
鏈接分享:http://muchs.cn/article4/ghecie.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、虛擬主機(jī)網(wǎng)站設(shè)計(jì)公司、外貿(mào)網(wǎng)站建設(shè)、定制網(wǎng)站、App開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站建設(shè)