SHELL 在指定行的前/後插入指定內容

#若是知道行號能夠用下面的方法正則表達式

sed -i '88 r b.file' a.file    #在a.txt的第88行插入文件b.txtshell

awk '1;NR==88{system("cat b.file")}' a.file > a.filevim

 

#若是不知道行號,能夠用正則匹配bash

sed -i '/regex/ r b.txt' a.txt # regex是正則表達式spa

awk '/target/{system("cat b.file")}' a.file > c.file.net

#sed的話若是不改變源文件,能夠去掉-i開關,修改會輸出到STDOUTscala

 

原文件:code

[root@xiaowu shell]# cat -n file 字符串

     1  aaaaget

     2  bbbb

     3  cccc

     4  dddd

 

如今要在第二行即「bbbb」行的下面添加一行,內容爲「xiaowu」

[root@xiaowu shell]# sed '/bbbb/a\xiaowu' file 

aaaa

bbbb

xiaowu

cccc

dddd

 

若是要加兩行「xiaowu」能夠用一下語句,注意用「\n」換行

[root@xiaowu shell]# sed '/bbbb/a\xiaowu\nxiaowu' file 

aaaa

bbbb

xiaowu

xiaowu

cccc

dddd

 

若是要在第二行即「bbbb」行的上添加一行,內容爲「xiaowu」,能夠把參數「a」換成「i」

[root@xiaowu shell]# sed '/b/i\xiaowu' file 

aaaa

xiaowu

bbbb

cccc

dddd

 

以上文件中只有一行匹配,若是文件中有兩行或者多行匹配,結果有是如何呢?

 

[root@xiaowu shell]# cat -n file 

     1  aaaa

     2  bbbb

     3  cccc

     4  bbbb

     5  dddd

 

[root@xiaowu shell]# sed '/bbbb/a\xiaowu' file 

aaaa

bbbb

xiaowu

cccc

bbbb

xiaowu

dddd

 

由結果可知,每一個匹配行的下一行都會被添加「xiaowu」

 

那麼若是指向在第二個「bbbb」的下一行添加內容「xiaowu」,該如何操做呢?

能夠考慮先獲取第二個「bbbb」行的行號,而後根據行號在此行的下一行添加「xiaowu」

 

獲取第二個「bbbb」行的行號的方法:

方法一:

[root@xiaowu shell]# cat -n file |grep b |awk '{print $1}'|sed -n "2"p

4

方法二:

[root@xiaowu shell]# sed -n '/bbbb/=' file |sed -n "2"p

4

由結果可知第二個「bbbb」行的行號爲4,而後再在第四行的前或後添加相應的內容:

[root@xiaowu shell]# sed -e '4a\xiaowu' file 

aaaa

bbbb

cccc

bbbb

xiaowu

dddd

[root@xiaowu shell]# sed -e '4a\xiaowu\nxiaowu' file 

aaaa

bbbb

cccc

bbbb

xiaowu

xiaowu

dddd

 

 

向指定行的末尾添加指定內容,好比在「ccccc」行的行尾介紹「 eeeee」

 

[root@xiaowu shell]# cat file

aaaaa

bbbbb

ccccc

ddddd

[root@xiaowu shell]# sed 's/cc.*/& eeeee/g' file

aaaaa

bbbbb

ccccc eeeee

ddddd

用Directory替換全部行中的Manager

[root@sishen ~]# sed 's/Manager/Director/' employee.txt

101,John Doe,CEO

102,Jason Smith,IT Director

103,Raj Reddy,Sysadmin

104,Anand Ram,Developer

105,Jane Miller,Sales Director

只把包含Sales的行中的Manager替換爲Director

[root@sishen ~]# sed '/Sales/s/Manager/Director/' employee.txt

101,John Doe,CEO

102,Jason Smith,IT Manager

103,Raj Reddy,Sysadmin

104,Anand Ram,Developer

105,Jane Miller,Sales Director

全局標誌 g

g表明全局(global)默認狀況下,sed會替換每行中第一次出現的original-string,若是你要替換每行中出現的全部original-string,就須要用g

示例 用大寫A替換第一次出現的小寫字母a

[root@sishen ~]# sed 's/a/A/' employee.txt

101,John Doe,CEO

102,JAson Smith,IT Manager

103,RAj Reddy,Sysadmin

104,AnAnd Ram,Developer

105,JAne Miller,Sales Manager

把全部小寫字母a替換爲大寫字母A

[root@sishen ~]# sed 's/a/A/g' employee.txt

101,John Doe,CEO

102,JAson Smith,IT MAnAger

103,RAj Reddy,SysAdmin

104,AnAnd RAm,Developer

105,JAne Miller,SAles ManAger

注意上述例子會在全部行上進行替換,由於沒有指定地址範圍

數字標誌(1,2,3,·····)

使用數字能夠指定original-string出現的次序,只有第n次出現的original-string纔會觸發替換,每行數字從1開始,最大爲512

好比/11會替換每行中第11次出現的original-string

把第二次出現的小寫字母a替換爲大寫字母A

[root@sishen ~]# sed 's/a/A/2' employee.txt

101,John Doe,CEO

102,Jason Smith,IT MAnager

103,Raj Reddy,SysAdmin

104,Anand RAm,Developer

105,Jane Miller,SAles Manager

爲了方便如下示例,首先創建以下文件

[root@sishen ~]# vim substitute-locate.txt

locate command is used to locate files

locate command uses datebases to locate files

locate command can also use regex for searching

~

把每行中第二次出的locate替換爲find

[root@sishen ~]# sed 's/locate/find/2' substitute-locate.txt

locate command is used to find files

lcaote command uses datebases to locate files

locate command can also use regex for searching

打印標誌p(print)

只打印替換後的行

[root@sishen ~]# sed -n 's/John/Johnny/p' employee.txt

101,Johnny Doe,CEO

在以前的數字標誌的例子中使用/2來替換第二次出現的locate。第3行中locate只出現了一次因此沒有替換任何內容,使用p標誌能夠只打印替換過的兩行

[root@sishen ~]# sed -n 's/locate/find/2p' substitute-locate.txt

locate command is used to find files

locate command uses datebases to find files

[root@sishen ~]#

寫標誌w

只把替換後的內容寫入到out6.txt文件中

[root@sishen ~]# sed -n 's/John/Johnny/w out6.txt' employee.txt

[root@sishen ~]# cat out6.txt

101,Johnny Doe,CEO

把每行中第二次出現的locate替換爲find,把替換後的結果保存到文件中,同時顯示輸入文件全部內容

[root@sishen ~]# sed 's/locate/find/2w out7.txt' substitute-locate.txt

locate command is used to find files

locate command uses datebases to find files

locate command can also use regex for searching

[root@sishen ~]# cat out7.txt

locate command is used to find files

locate command uses datebases to find files

[root@sishen ~]# sed -n 's/locate/find/2w out7.txt' substitute-locate.txt

[root@sishen ~]# cat out7.txt

locate command is used to find files

locate command uses datebases to find files

[root@sishen ~]#

注意加上-n參數就不會輸出顯示在屏幕上

忽略大小寫標誌i(ignore)

[root@sishen ~]# sed 's/john/Johnny/' employee.txt

101,John Doe,CEO

102,Jason Smith,IT Manager

103,Raj Reddy,Sysadmin

104,Anand Ram,Developer

105,Jane Miller,Sales Manager

加上-i參數後才能夠實現替換

[root@sishen ~]# sed 's/john/Johnny/i' employee.txt

101,Johnny Doe,CEO

102,Jason Smith,IT Manager

103,Raj Reddy,Sysadmin

104,Anand Ram,Developer

105,Jane Miller,Sales Manager

執行命令標誌w(excuate)

首先創建文件bash-file.txt

[root@sishen ~]# cat bash-file.txt

/etc/passwd

/etc/group

在bash-file.txt文件中的每行前面添加 ls -l 並打印結果

[root@sishen ~]# sed 's/^/ls -l/' bash-file.txt

ls -l/etc/passwd

ls -l/etc/group

在bash-file文件中的每行前面添加ls -l 並把結果做爲命令執行

[root@sishen ~]# sed 's/^/ls -l /e' bash-file.txt

-rw-r--r-- 1 root root 1623 Oct 12 10:23 /etc/passwd

-rw-r--r-- 1 root root 818 Oct 12 10:23 /etc/group

使用替換標誌組合

使用g,I,p和w的組合

下面的例子將把每行中出現的全部Manager或manager替換爲Directory。而後把替換後的內容打印到屏幕上,同時把這些內容保存到out8.txt文件中

[root@sishen ~]# sed -n 's/manager/Director/igpw out8.txt' employee.txt

102,Jason Smith,IT Director

105,Jane Miller,Sales Director

sed替換命令分界符

首先新建一個文件path.txt

reading /usr/local/bin directory

限制使用sed把/usr/local/bin替換爲/usr/bin,在下面的例子中,sed默認的分界符/都被\轉義

[root@sishen ~]# sed 's/\/usr\/local\/bin/\/usr\/bin/' path.txt

reading /usr/bin directory

這樣雖然實現了替換,可是操做中很繁瑣,因此你可使用任何一個字符(包括字母,可是不建議這樣作)

做爲sed替換命令的分界符。如 | 或 ^ 或!如

[root@sishen ~]# sed 'sA/usr/local/bin/A/usr/bin/A' path.txt

reading /usr/local/bin directory

[root@sishen ~]# sed 's|/usr/local/bin|/usr/bin|' path.txt

reading /usr/bin directory

[root@sishen ~]# sed 's@/usr/local/bin@/usr/bin/@' path.txt

reading /usr/bin/ directory

[root@sishen ~]# sed 's^/usr/local/bin^/usr/bin^' path.txt

reading /usr/bin directory

[root@sishen ~]# sed 's!/usr/local/bin!/usr/bin!' path.txt

reading /usr/bin directory

結果都同樣,看本身喜愛了

單行內容以上執行多個命令

下面的例子演示了在模式空間內執行兩個替換命令的過程

[root@sishen ~]# sed '{

> s/Developer/IT Manager/

> s/Manager/Director/

> }' employee.txt #注意空格

101,John Doe,CEO

102,Jason Smith,IT Director

103,Raj Reddy,Sysadmin

104,Anand Ram,IT Director

105,Jane Miller,Sales Director

分析第4行執行過程

1. 讀取數據:在這一步,sed讀取內容到模式空間,此時模式空間的內容爲:

104,Ananda Ram,Developer

2. 執行命令:第一個命令,s/Developer/IT Manager/執行後,模式空間的內容爲:

104,Anand Ram,IT Manager

如今在模式空間上執行第二個命令s/Manager/Director/,執行後,模式空間內容爲:

104,Ananda Ram,IT Director

謹記:sed在第一個命令執行的結果上,執行第二個命令

3. 打印內容:打印當前模式空間的內容,以下

104,Ananda Ram,IT Director

4. 重複循環:移動到輸入文件的下一行,而後重複執行第一步,即讀取數據

&的做用----獲取匹配到的模式

擋在replacement-string中使用&時,它會被替換成匹配到的original-string或正則表達式,這是個頗有用的東西

給僱員ID(即第一列的3個數字)加上[ ],如101改爲[101]

[root@sishen ~]# sed 's/^[0-9][0-9][0-9]/[&]/g' employee.txt

[101],John Doe,CEO

[102],Jason Smith,IT Manager

[103],Raj Reddy,Sysadmin

[104],Anand Ram,Developer

[105],Jane Miller,Sales Manager

把每一行放進<>中

[root@sishen ~]# sed 's/^.*/<&>/' employee.txt

<101,John Doe,CEO>

<102,Jason Smith,IT Manager>

<103,Raj Reddy,Sysadmin>

<104,Anand Ram,Developer>

<105,Jane Miller,Sales Manager>

分組替換(單個分組)

跟正則表達式中同樣,sed中也可使用分組,分組以\(開始,以\)結束,分組能夠用在回溯引用中,

回溯引用即從新使用分組所選擇的部分正則表達式,在sed替換命令的replacement-string中和正則表達式中,均可以使用回溯引用,

單個分組

[root@sishen ~]# sed 's/\([^,]*\).*/\1/g' employee.txt

101

102

103

104

105

上面例子中:

l 正則表達式\([^,0]*/)匹配字符串從開頭到一個逗號之間的全部字符(並將其放入第一個分組中)

l Replacement-string中的\1將代替匹配到的分組

l g 便是全局標誌

下面例子只會顯示/etc/passwd的第一列,即用戶名

[root@sishen ~]# sed 's/\([^:]*\).*/\1/' /etc/passwd

root

bin

daemon

adm

lp

sync

shutdown

halt

mail

uucp

operator

……

首先創建下面文件,以便使用

[root@sishen ~]# vim number.txt

1

12

123

1234

12345

123456

~

格式化輸出,增長可讀性

[root@sishen ~]# sed 's/\(^\|[^0-9.]\)\([0-9]\+\)\([0-9]\{3\}\)/\1\2,\3/g' number.txt

1

12

123

1,234

12,345

123,456

分組替換(多個分組)

可使用多個\和(\)

劃分多個分組,使用多個分組時,須要在replacement-string中使用\n來指定第n個分組,以下面的示例如只打印第一列(僱員ID)和第3列(僱員職位)

[root@sishen ~]# sed 's/^\([^,]*\),\([^,]*\),\([^,*]\)/\1,\3/' employee.txt

101,CEO

102,IT Manager

103,Sysadmin

104,Developer

105,Sales Manager

在這個例子中能夠看到,original-string中,劃分了3個分組,以逗號分隔

l ([^,]*\)第一個分組,匹配僱員ID

l ,爲字段分隔符

l ([^,]*\)爲第二個分組,匹配僱員姓名

l ,爲字段分割符,上面的例子演示瞭如何使用分組

l \1表明第一個分組,(僱員ID)

l ,出如今第一個分組以後的逗號

l \3表明第二個分組(僱員職位)

注意:sed最多能處理9個分組,分別用\1至\9表示

交換第一列(僱員ID)和第二列(僱員姓名)

[root@sishen ~]# sed 's/^\([^,]*\),\([^,]*\),\([^,]*\)/\2,\1,\3/' employee.txt

John Doe,101,CEO

Jason Smith,102,IT Manager

Raj Reddy,103,Sysadmin

Anand Ram,104,Developer

Jane Miller,105,Sales Manager

sed專有的替換標誌

\l 標誌(小寫的 L,理解爲lower)

當在replacement-string中使用\l標誌時,它會把緊跟在其後的字符看成小寫字符來處理,如你所知,下面的例子將把John換成JOHNNY:

[root@sishen ~]# sed -n 's/John/JOHNNY/p' employee.txt

101,JOHNNY Doe,CEO

下面的例子將把JOHNNY 中的H換成h

[root@sishen ~]# sed -n 's/John/JO\lHNNY/p' employee.txt

101,JOhNNY Doe,CEO

\L 標誌

當在replacement-string中使用\L標誌時,它會把後面全部的字符都當小寫字符來處理,例如:

在replacement-string中的H前放置了\L 標誌,它會把H和它後面的全部字符都換成小寫:

[root@sishen ~]# sed -n 's/John/JO\LHNNY/p' employee.txt

101,JOhnny Doe,CEO

\u標誌(理解爲upper)和\l相似,只不過是把字符換成大寫,當在replacemen-string中使用\u標誌時,它會把緊跟其後的字符看成大寫字符來處理,下面的例子中,replacement-string裏面的h前面有\u的標誌,因此h將被換成大寫的H:

[root@sishen ~]# sed -n 's/John/jo\uhnny/p' employee.txt

101,joHnny Doe,CEO

\U標誌

當在replacement-string中使用\U標誌時,它會把後面全部的字符都看成大寫字符來處理。以下:replacement-string裏面的h前面有U的標誌,因此h及其後的全部字符都將被換成大寫:

[root@sishen ~]# sed -n 's/John/jo\Uhnny/p' employee.txt

101,joHNNY Doe,CEO

\E標誌(理解爲exit)

\E標誌須要和\U或者\L一塊兒使用,他將關閉\U或\L的功能,例如將字符串「Johnny Boy」的每一個字符都以大寫的形式打印出來,由於在replacement-string前面使用了\U標誌

[root@sishen ~]# sed -n 's/John/\UJohnny Boy/p' employee.txt

101,JOHNNY BOY Doe,CEO

下面將把John換成JOHNNY Boy

[root@sishen ~]# sed -n 's/John/\UJohnny\E Boy/p' employee.txt

101,JOHNNY Boy Doe,CEO

由於在Johnny後面使用了\E標誌,關閉了\U的功能

替換標誌的用法

以下將僱員ID都顯示爲大寫,職位都顯示爲小寫:

[root@sishen ~]# sed 's/\([^,]*\),\([^,]*\),\([^,]*\)/\U\2\E,\1,\L\3/' employee.txt

JOHN DOE,101,ceo

JASON SMITH,102,it manager

RAJ REDDY,103,sysadmin

ANAND RAM,104,developer

JANE MILLER,105,sales manager

這個例子中

l \U\2\3把第二個分組轉換爲大寫,而後使用\E關閉轉換

l \L\3 把第三分組轉換爲小寫

mac環境下的幾個使用例子:

一、將a.txt中的public request所有替換成public requestUrl
sed -i ".bak" 's/public request/public requestUrl/g' a.txt

二、在a.txt的第66行插入test字符串
sed -i -e '66a \                        //注意此處必須換行
test' a.txt

三、在a.txt中包含public scalar的行下,插入test字符串
sed -i "" '/public scale/a \
test' a.txt

四、在a.txt的第16行插入b.txt內容,例如b.txt在/home/b.txt,則$1即爲/home,拼完整路徑也可
sed -i ".bak" '16 r '$1'/b.txt' a.txt

五、在a.txt中bb/bb行下,插入c.txt內容
sed -i ".bak" '/bb\/bb/ r c.txt' a.txt

六、只替換首次出現符合條件的字符串,如將a.txt中首次出現value:true的替換爲value:false
sed -i ".bak" '1,/value: true/ s/value: true/value: false/' a.txt

七、將a.txt中,每行第2次出現的a替換爲A
sed 's/a/A/2' a.txt
相關文章
相關標籤/搜索