文章目錄
sed是一個流編輯器,用于對文件或輸入流執行各種文本轉換,功能強大且效率高。
主要用于對數據行進行替換、刪除、新增、修改等。
一、sed 語法格式
sed [-nefri] 'command' 輸入文本
參數選項
| 常見參數 | 說明 |
|---|
| -n | 抑制輸出,結合p指令打印特定行。 默認sed會列出所有指定內容,加上 -n 參數后,則只有經過sed 特殊處理的那一行才會被列出來。 |
| -i | 直接修改文件內容,而且不進行任何輸出,慎用! 默認情況下 sed 并不直接修改文件內容,只是把結果進行標準輸出,文件內容實際沒有變化。 |
| -e | 使用后面的動作指令編輯文件內容 |
| -f | 直接將 sed 的動作寫在一個檔案內, -f filename 則可以執行 filename 內的sed 動作; |
動作指令
使用時要用單引號把動作指令內容括起來;
若指令內容包含變量,則用雙引號括起來。
| 常用動作 | 說明 |
|---|
| p | print,打印,列出指定的內容,通常與 -n 參數一起使用 |
| a | after,新增,后面接字符串,并顯示在新的一行(目前的下一行) |
| i | insert,插入, 后面接字符串,并顯示在新的一行(目前的上一行) |
| c | change,替換一行或多行的整行內容,后面接字符串,用于取代 n1,n2 之間的行 |
| s | supersede,stead,替換一行或多行中的部分內容,通常搭配正規表達式 常用方式: 1,20s/old/new/g |
| d | delete,刪除,后面通常不接任何字符 |
二、參數使用舉例
(假設我們有一文件名為input)
1、輸入文件的幾種方式
sed 命令中的文件參數可以是文件名,也可以是來自管道的輸入。
下面幾種方式是等價的:
sed 's/hello/world/g' input > output
sed 's/hello/world/g' < input> output
cat input | sed 's/hello/world/g' - > output
cat input | sed 's/hello/world/g' > output # - 可以省略
2、-n 抑制輸出
默認情況下,sed打印所有已處理的輸入(已通過命令修改/刪除的輸入除外)。
使用 -n 抑制輸出,結合p指令可以打印特定行。
僅打印輸入文件的第45行:
sed -n '45p' input
3、-i 修改文件內容且不進行輸出
查看input文件原內容:
$ cat input
hello ehllo hello
hello abadbsabf
a123gdsgahello
sed 不帶 -i 參數時進行替換指令
會輸出替換后的結果,且再次查看input內容,原文件未修改。
# sed 替換
$ sed 's/hello/world/' input
world ehllo hello
world abadbsabf
a123gdsgaworld
# 查看input內容,并未真正修改
$ cat input
hello ehllo hello
hello abadbsabf
a123gdsgahello
sed -i 進行替換指令
不會輸出任何內容,且再次查看input內容,原文件直接被修改了。
$ sed -i 's/hello/world/' input
$ cat input
world ehllo hello
world abadbsabf
a123gdsgaworld
sed -i 使用正則表達式匹配
$ cat input.txt
google.
taobao.
zhihu-
$ sed -i 's/\.$/\!/g' input.txt
$ cat input.txt
google!
taobao!
zhihu-
(這個命令把選項 -i 和指令 a 結合使用,同時其中 $ 代表最后一行,從而實現直接修改文件,在最后一行后面新增內容。)
$ sed -i '$a # This is a test' input.txt
$ cat input.txt
google!
taobao!
zhihu-
# This is a test
4、-e 和 -f 指定腳本
4.1 語法:
-e 指定動作集(兩種方式一樣):
-e script
–expression=script
-f 指定動作文件(兩種方式一樣):
-f script-file
–file=script-file
4.2 下面幾種示例是等價的:
sed 's/hello/world/' input.txt > output.txt
sed -e 's/hello/world/' input.txt > output.txt
sed --expression='s/hello/world/' input.txt > output.txt
echo 's/hello/world/' > myscript.sed
sed -f myscript.sed input.txt > output.txt
sed --file=myscript.sed input.txt > output.txt
4.3 使用 -e實現多個匹配
默認情況下,一條sed命令只能有一個編輯指令;
若要實現同時執行多個編輯指令,有如下幾種方式:
通過 -f 指定腳本文件,在文件中集合多條指令;
通過管道符|連接多條 sed 指令;
- 在一條sed指令中使用多個
-e選項實現。
在一條sed命令中,刪除/etc/passwd第三行到末尾的數據,并把bash替換為blueshell:
$ nl /etc/passwd | sed -e '3,$d' -e 's/bash/blueshell/'
1 root:x:0:0:root:/root:/bin/blueshell
2 daemon:x:1:1:daemon:/usr/sbin:/bin/sh
三、各指令使用舉例
1、p 打印某行
| 命令 | 說明 |
|---|
| sed ‘1p’ filename | 先打印第一行,然后再打印所有行 |
| sed -n ‘1p’ filename | 打印第一行 |
| sed -n ‘$p’ filename | 打印最后一行 |
| sed -n ‘1,2p’ filename | 打印第一行到第二行 |
| sed -n ‘2,$p’ filename | 打印第二行到最后一行 |
| sed ‘/yuance/p’ filename | 先打印包含yuance的行,再打印所有行 |
| sed -n ‘/yuance/p’ filename | 打印包含yuance的行 |
| sed -n ‘/$/p’ filename | 打印包括關鍵字 $ 所在的行,使用反斜線 \ 屏蔽特殊含義 |
2、d刪除某行
d --delete, 可指定區間,‘1,Nd’
與 p指令用法類似
- 默認會打印出刪除指定行后,其它行的內容,但是原文件內容不變
| 命令 | 說明 |
|---|
| sed ‘3d’ filename | 刪除第三行 |
| sed ‘$d’ filename | 刪除最后一行 |
| sed ‘1,2d’ filename | 刪除第一行到第二行 |
| sed ‘2,$d’ filename | 刪除第二行到最后一行 |
| sed ‘/pattern/d’ filename | 刪除包含pattern關鍵字的所有行 |
$ cat input
world ehllo hello
world abadbsabf
a123gdsgaworld
1241
$ sed '4d' input
world ehllo hello
world abadbsabf
a123gdsgaworld
$ cat input
world ehllo hello
world abadbsabf
a123gdsgaworld
1241
3、a增加一行或多行字符串(在下一行)
| 命令 | 說明 |
|---|
| sed ‘1a drink tea’ filename | 第一行后增加字符串"drink tea" |
| sed ‘1,3a drink tea’ filename | 第一行到第三行后增加字符串"drink tea" |
| sed ‘$a drink bye’ filename | 最后一行后增加字符串"bye" |
| sed ‘1a drink tea\nor coffee’ filename | 第一行后增加兩行"drink tea"和"or coffee" |
| sed ‘1a drink tea’ filename | 第一行后增加字符串"drink tea" |
$ cat input.txt
Hello!
jing is me,welcome to my blog.
end
第一行后增加字符串"drink tea"
$ sed '1a drink tea' input.txt
Hello!
drink tea
jing is me,welcome to my blog.
end
第一行到第三行后增加字符串"drink tea"
$ sed '1,3a drink tea' input.txt
Hello!
drink tea
jing is me,welcome to my blog.
drink tea
end
drink tea
增加多行,使用換行符 "\n"
$ sed '1a drink tea\nor coffee' input.txt
Hello!
drink tea
or coffee
jing is me,welcome to my blog.
end
4、i插入一行或多行(在上一行)
todo
5、c對一行或多行進行整行替換
第一行代替為 "Hi"
$ sed '1c Hi' input.txt
Hi
jing is me,welcome to my blog.
end
第一行到第二行代替為 "Hi"
$ sed '1,2c Hi' ab
Hi
end
將第2-5行的內容取代成為"No 2-5 number"(其中"nl"是帶行號輸出):
$ nl /etc/passwd | sed '2,5c No 2-5 number'
1 root:x:0:0:root:/root:/bin/bash
No 2-5 number
6 sync:x:5:0:sync:/sbin:/bin/sync
.....(后面省略).....
6、s替換一行中的部分內容
6.1 格式 ‘s/xx/xx/g’:
sed 's/要替換的字符串/新的字符串/g' (要替換的字符串可以用正則表達式)
| 命令 | 說明 |
|---|
| sed ‘s/cat/bird/g’ filename | 把文件中所有的’cat’替換成’bird’ |
| sed ‘s/cat//g’ filename | 刪除文件中所有的’cat’(替換為空即刪除) |
| sed ‘s/unix/linux/’ filename | 把每一行中的第 1 次出現的’unix’替換成’linux’ |
| sed ‘s/unix/linux/3’ filename | 把每一行中的第 3 次出現的’unix’替換成’linux’ |
| sed ‘s/unix/linux/4g’ filename | 把每一行中第 4 次開始到最后出現的’unix’全部替換成’linux’ |
| sed ‘3 s/unix/linux/’ filename | 在’s’前加數字,可對指定行進行替換。 把第 3 行中第一次出現的’unix’替換成’linux’。 |
| sed ‘3,7 s/unix/linux/’ filename | 在’s’前也可以加數字范圍,對多行進行替換。 把第 3-7 行中第一次出現的’unix’替換成’linux’。 |
| sed ‘3,$ s/unix/linux/’ filename | 把第 3行至結尾行每行第一次出現的’unix’替換成’linux’。 |
| nl filename | sed -n ‘7 s/unix/linux/p’ | 把第 7 行中第一次出現的’unix’替換成’linux’,并把替換后的第7行打印出來。 若加了 -n 不加的后面的 p ,則替換后不打印。 |
6.2 匹配字符串中使用正則表達式
| 原字符串 | 命令 | 匹配結果 |
|---|
| inet addr:192.168.1.100 | sed 's/^.*addr://g’ | 192.168.1.100 |
| 192.168.1.100 Bcast:192.168.1.255 | sed 's/Bcast.*$//g’ | 192.168.1.100 |
| hello world | sed 's/^/#/g’ | #hello world,即在每行開頭加上 # |
| hello world | sed 's/$/—/g’ | hello world---,即在每行最后加上 — |
6.3 替換匹配行中的某個字符串
sed '/匹配字符串/s/替換源字符串/替換目標字符串/g' filename
先進行字符串匹配;
然后對匹配到的行進行字符串替換。