| 1 | 1/1 | 返回列表 |
| 查看: 413 | 回復(fù): 0 | |||
langerdan金蟲 (初入文壇)
|
[交流]
【轉(zhuǎn)】sed 簡明教程
|
|
awk于1977年出生,今年36歲本命年,sed比awk大2-3歲,awk就像林妹妹,sed就是寶玉哥哥了。所以 林妹妹跳了個(gè)Topless,他的哥哥sed坐不住了,也一定要出來抖一抖。 sed全名叫stream editor,流編輯器,用程序的方式來編輯文本,相當(dāng)?shù)膆acker啊。sed基本上就是玩正則模式匹配,所以,玩sed的人,正則表達(dá)式一般都比較強(qiáng)。 同樣,本篇文章不會說sed的全部東西,你可以參看sed的手冊,我這里主要還是想和大家競爭一下那些從手機(jī)指縫間或馬桶里流走的時(shí)間,用這些時(shí)間來學(xué)習(xí)一些東西。當(dāng)然,接下來的還是要靠大家自己雙手。 用s命令替換 我使用下面的這段文本做演示: $ cat pets.txt This is my cat my cat's name is betty This is my dog my dog's name is frank This is my fish my fish's name is george This is my goat my goat's name is adam 把其中的my字符串替換成Hao Chen’s,下面的語句應(yīng)該很好理解(s表示替換命令,/my/表示匹配my,/Hao Chen’s/表示把匹配替換成Hao Chen’s,/g 表示一行上的替換所有的匹配): $ sed "s/my/Hao Chen's/g" pets.txt This is Hao Chen's cat Hao Chen's cat's name is betty This is Hao Chen's dog Hao Chen's dog's name is frank This is Hao Chen's fish Hao Chen's fish's name is george This is Hao Chen's goat Hao Chen's goat's name is adam 注意:如果你要使用單引號,那么你沒辦法通過\’這樣來轉(zhuǎn)義,就有雙引號就可以了,在雙引號內(nèi)可以用\”來轉(zhuǎn)義。 再注意:上面的sed并沒有對文件的內(nèi)容改變,只是把處理過后的內(nèi)容輸出,如果你要寫回文件,你可以使用重定向,如: $ sed "s/my/Hao Chen's/g" pets.txt > hao_pets.txt 或使用 -i 參數(shù)直接修改文件內(nèi)容: $ sed -i "s/my/Hao Chen's/g" pets.txt 在每一行最前面加點(diǎn)東西: $ sed 's/^/#/g' pets.txt #This is my cat # my cat's name is betty #This is my dog # my dog's name is frank #This is my fish # my fish's name is george #This is my goat # my goat's name is adam 在每一行最后面加點(diǎn)東西: $ sed 's/$/ --- /g' pets.txt This is my cat --- my cat's name is betty --- This is my dog --- my dog's name is frank --- This is my fish --- my fish's name is george --- This is my goat --- my goat's name is adam --- 順手介紹一下正則表達(dá)式的一些最基本的東西: •^ 表示一行的開頭。如:/^#/ 以#開頭的匹配。 •$ 表示一行的結(jié)尾。如:/}$/ 以}結(jié)尾的匹配 •\< 表示詞首。 如 \ 表示詞尾。 如 abc\> 表示以 abc 結(jié)尾的詞. •. 表示任何單個(gè)字符。 •* 表示某個(gè)字符出現(xiàn)了0次或多次。 •[ ] 字符集合。 如:[abc]表示匹配a或b或c,還有[a-zA-Z]表示匹配所有的26個(gè)字符。如果其中有^表示反,如[^a]表示非a的字符 正規(guī)則表達(dá)式是一些很牛的事,比如我們要去掉某html中的tags: <b>This</b> is what <span style="text-decoration: underline;">I</span> meant. Understand? 看看我們的sed命令 # 如果你這樣搞的話,就會有問題 $ sed 's/<.*>//g' html.txt Understand? # 要解決上面的那個(gè)問題,就得像下面這樣。 # 其中的'[^>]' 指定了除了>的字符重復(fù)0次或多次。 $ sed 's/<[^>]*>//g' html.txt This is what I meant. Understand? 我們再來看看指定需要替換的內(nèi)容: $ sed "3s/my/your/g" pets.txt This is my cat my cat's name is betty This is your dog my dog's name is frank This is my fish my fish's name is george This is my goat my goat's name is adam 下面的命令只替換第3到第6行的文本。 $ sed "3,6s/my/your/g" pets.txt This is my cat my cat's name is betty This is your dog your dog's name is frank This is your fish your fish's name is george This is my goat my goat's name is adam $ cat my.txt This is my cat, my cat's name is betty This is my dog, my dog's name is frank This is my fish, my fish's name is george This is my goat, my goat's name is adam 只替換每一行的第一個(gè)s: $ sed 's/s/S/1' my.txt ThiS is my cat, my cat's name is betty ThiS is my dog, my dog's name is frank ThiS is my fish, my fish's name is george ThiS is my goat, my goat's name is adam 只替換每一行的第二個(gè)s: $ sed 's/s/S/2' my.txt This iS my cat, my cat's name is betty This iS my dog, my dog's name is frank This iS my fish, my fish's name is george This iS my goat, my goat's name is adam 只替換第一行的第3個(gè)以后的s: $ sed 's/s/S/3g' my.txt This is my cat, my cat'S name iS betty This is my dog, my dog'S name iS frank This is my fiSh, my fiSh'S name iS george This is my goat, my goat'S name iS adam 多個(gè)匹配 如果我們需要一次替換多個(gè)模式,可參看下面的示例:(第一個(gè)模式把第一行到第三行的my替換成your,第二個(gè)則把第3行以后的This替換成了That) $ sed '1,3s/my/your/g; 3,$s/This/That/g' my.txt This is your cat, your cat's name is betty This is your dog, your dog's name is frank That is your fish, your fish's name is george That is my goat, my goat's name is adam 上面的命令等價(jià)于:(注:下面使用的是sed的-e命令行參數(shù)) sed -e '1,3s/my/your/g' -e '3,$s/This/That/g' my.txt 我們可以使用&來當(dāng)做被匹配的變量,然后可以在基本左右加點(diǎn)東西。如下所示: $ sed 's/my/[&]/g' my.txt This is [my] cat, [my] cat's name is betty This is [my] dog, [my] dog's name is frank This is [my] fish, [my] fish's name is george This is [my] goat, [my] goat's name is adam 圓括號匹配 使用圓括號匹配的示例:(圓括號括起來的正則表達(dá)式所匹配的字符串會可以當(dāng)成變量來使用,sed中使用的是\1,\2…) $ sed 's/This is my \([^,]*\),.*is \(.*\)/\1:\2/g' my.txt cat:betty dog:frank fish:george goat:adam 上面這個(gè)例子中的正則表達(dá)式有點(diǎn)復(fù)雜,解開如下(去掉轉(zhuǎn)義字符): 正則為:This is my ([^,]*),.*is (.*) 匹配為:This is my (cat),……….is (betty) 然后:\1就是cat,\2就是betty sed的命令 讓我們回到最一開始的例子pets.txt,讓我們來看幾個(gè)命令: N命令 先來看N命令 —— 把下一行的內(nèi)容納入當(dāng)成緩沖區(qū)做匹配。 下面的的示例會把原文本中的偶數(shù)行納入奇數(shù)行匹配,而s只匹配并替換一次,所以,就成了下面的結(jié)果: $ sed 'N;s/my/your/' pets.txt This is your cat my cat's name is betty This is your dog my dog's name is frank This is your fish my fish's name is george This is your goat my goat's name is adam 也就是說,原來的文件成了: This is my cat\n my cat's name is betty This is my dog\n my dog's name is frank This is my fish\n my fish's name is george This is my goat\n my goat's name is adam 這樣一來,下面的例子你就明白了, $ sed 'N;s/\n/,/' pets.txt This is my cat, my cat's name is betty This is my dog, my dog's name is frank This is my fish, my fish's name is george This is my goat, my goat's name is adam a命令和i命令 a命令就是append, i命令就是insert,它們是用來添加行的。如: # 其中的1i表明,其要在第1行前插入一行(insert) $ sed "1 i This is my monkey, my monkey's name is wukong" my.txt This is my monkey, my monkey's name is wukong This is my cat, my cat's name is betty This is my dog, my dog's name is frank This is my fish, my fish's name is george This is my goat, my goat's name is adam # 其中的1a表明,其要在最后一行后追加一行(append) $ sed "$ a This is my monkey, my monkey's name is wukong" my.txt This is my cat, my cat's name is betty This is my monkey, my monkey's name is wukong This is my dog, my dog's name is frank This is my fish, my fish's name is george This is my goat, my goat's name is adam 我們可以運(yùn)用匹配來添加文本: # 注意其中的/fish/a,這意思是匹配到/fish/后就追加一行 $ sed "/fish/a This is my monkey, my monkey's name is wukong" my.txt This is my cat, my cat's name is betty This is my dog, my dog's name is frank This is my fish, my fish's name is george This is my monkey, my monkey's name is wukong This is my goat, my goat's name is adam 下面這個(gè)例子是對每一行都挺插入: $ sed "/my/a ----" my.txt This is my cat, my cat's name is betty ---- This is my dog, my dog's name is frank ---- This is my fish, my fish's name is george ---- This is my goat, my goat's name is adam ---- c命令 c 命令是替換匹配行 $ sed "2 c This is my monkey, my monkey's name is wukong" my.txt This is my cat, my cat's name is betty This is my monkey, my monkey's name is wukong This is my fish, my fish's name is george This is my goat, my goat's name is adam $ sed "/fish/c This is my monkey, my monkey's name is wukong" my.txt This is my cat, my cat's name is betty This is my dog, my dog's name is frank This is my monkey, my monkey's name is wukong This is my goat, my goat's name is adam d命令 刪除匹配行 $ sed '/fish/d' my.txt This is my cat, my cat's name is betty This is my dog, my dog's name is frank This is my goat, my goat's name is adam $ sed '2d' my.txt This is my cat, my cat's name is betty This is my fish, my fish's name is george This is my goat, my goat's name is adam $ sed '2,$d' my.txt This is my cat, my cat's name is betty p命令 打印命令 你可以把這個(gè)命令當(dāng)成grep式的命令 # 匹配fish并輸出,可以看到fish的那一行被打了兩遍, # 這是因?yàn)閟ed處理時(shí)會把處理的信息輸出 $ sed '/fish/p' my.txt This is my cat, my cat's name is betty This is my dog, my dog's name is frank This is my fish, my fish's name is george This is my fish, my fish's name is george This is my goat, my goat's name is adam # 使用n參數(shù)就好了 $ sed -n '/fish/p' my.txt This is my fish, my fish's name is george # 從一個(gè)模式到另一個(gè)模式 $ sed -n '/dog/,/fish/p' my.txt This is my dog, my dog's name is frank This is my fish, my fish's name is george #從第一行打印到匹配fish成功的那一行 $ sed -n '1,/fish/p' my.txt This is my cat, my cat's name is betty This is my dog, my dog's name is frank This is my fish, my fish's name is george 幾個(gè)知識點(diǎn) 好了,下面我們要介紹四個(gè)sed的基本知識點(diǎn): Pattern Space 第零個(gè)是關(guān)于-n參數(shù)的,大家也許沒看懂,沒關(guān)系,我們來看一下sed處理文本的偽代碼,并了解一下Pattern Space的概念: foreach line in file { //放入把行Pattern_Space Pattern_Space <= line; // 對每個(gè)pattern space執(zhí)行sed命令 Pattern_Space <= EXEC(sed_cmd, Pattern_Space); // 如果沒有指定 -n 則輸出處理后的Pattern_Space if (sed option hasn't "-n" {print Pattern_Space } } Address 第一個(gè)是關(guān)于address,幾乎上述所有的命令都是這樣的(注:其中的!表示匹配成功后是否執(zhí)行命令) [address[,address]][!]{cmd} address可以是一個(gè)數(shù)字,也可以是一個(gè)模式,你可以通過逗號要分隔兩個(gè)address 表示兩個(gè)address的區(qū)間,參執(zhí)行命令cmd,偽代碼如下: bool bexec = false foreach line in file { if ( match(address1) ){ bexec = true; } if ( bexec == true) { EXEC(sed_cmd); } if ( match (address2) ) { bexec = false; } } 關(guān)于address可以使用相對位置,如: # 其中的+3表示后面連續(xù)3行 $ sed '/dog/,+3s/^/# /g' pets.txt This is my cat my cat's name is betty # This is my dog # my dog's name is frank # This is my fish # my fish's name is george This is my goat my goat's name is adam 命令打包 第二個(gè)是cmd可以是多個(gè),它們可以用分號分開,可以用大括號括起來作為嵌套命令。下面是幾個(gè)例子: $ cat pets.txt This is my cat my cat's name is betty This is my dog my dog's name is frank This is my fish my fish's name is george This is my goat my goat's name is adam # 對3行到第6行,執(zhí)行命令/This/d $ sed '3,6 {/This/d}' pets.txt This is my cat my cat's name is betty my dog's name is frank my fish's name is george This is my goat my goat's name is adam # 對3行到第6行,匹配/This/成功后,再匹配/fish/,成功后執(zhí)行d命令 $ sed '3,6 {/This/{/fish/d}}' pets.txt This is my cat my cat's name is betty This is my dog my dog's name is frank my fish's name is george This is my goat my goat's name is adam # 從第一行到最后一行,如果匹配到This,則刪除之;如果前面有空格,則去除空格 $ sed '1,${/This/d;s/^ *//g}' pets.txt my cat's name is betty my dog's name is frank my fish's name is george my goat's name is adam Hold Space 第三個(gè)我們再來看一下 Hold Space 接下來,我們需要了解一下Hold Space的概念,我們先來看四個(gè)命令: g: 將hold space中的內(nèi)容拷貝到pattern space中,原來pattern space里的內(nèi)容清除 G: 將hold space中的內(nèi)容append到pattern space\n后 h: 將pattern space中的內(nèi)容拷貝到hold space中,原來的hold space里的內(nèi)容被清除 H: 將pattern space中的內(nèi)容append到hold space\n后 x: 交換pattern space和hold space的內(nèi)容 這些命令有什么用?我們來看兩個(gè)示例吧,用到的示例文件是: $ cat t.txt one two three 第一個(gè)示例: $ sed 'H;g' t.txt one one two one two three 是不是有點(diǎn)沒看懂,我作個(gè)圖你就看懂了。 第二個(gè)示例,反序了一個(gè)文件的行: $ sed '1!G;h;$!d' t.txt three two one 其中的 ’1!G;h;$!d’ 可拆解為三個(gè)命令 •1!G —— 只有第一行不執(zhí)行G命令,將hold space中的內(nèi)容append回到pattern space •h —— 第一行都執(zhí)行h命令,將pattern space中的內(nèi)容拷貝到hold space中 •$!d —— 除了最后一行不執(zhí)行d命令,其它行都執(zhí)行d命令,刪除當(dāng)前行 這個(gè)執(zhí)行序列很難理解,做個(gè)圖如下大家就明白了: |

| 1 | 1/1 | 返回列表 |
| 最具人氣熱帖推薦 [查看全部] | 作者 | 回/看 | 最后發(fā)表 | |
|---|---|---|---|---|
|
[考研] 279求調(diào)劑 +3 | 紅衣隱官 2026-03-21 | 3/150 |
|
|---|---|---|---|---|
|
[考研] 268求調(diào)劑 +7 | 簡單點(diǎn)0 2026-03-17 | 7/350 |
|
|
[考研] 316求調(diào)劑 +6 | 梁茜雯 2026-03-19 | 6/300 |
|
|
[考研] 346求調(diào)劑[0856] +4 | WayneLim327 2026-03-16 | 7/350 |
|
|
[考研] 機(jī)械專碩299求調(diào)劑至材料 +3 | kkcoco25 2026-03-16 | 4/200 |
|
|
[考研] 301求調(diào)劑 +10 | yy要上岸呀 2026-03-17 | 10/500 |
|
|
[考研] 初始318分求調(diào)劑(有工作經(jīng)驗(yàn)) +3 | 1911236844 2026-03-17 | 3/150 |
|
|
[考研] 一志愿中國石油大學(xué)(華東) 本科齊魯工業(yè)大學(xué) +3 | 石能偉 2026-03-17 | 3/150 |
|
|
[考研] 280求調(diào)劑 +7 | 咕嚕曉曉 2026-03-18 | 8/400 |
|
|
[考研] 一志愿武理材料305分求調(diào)劑 +6 | 想上岸的鯉魚 2026-03-18 | 7/350 |
|
|
[考研] 311求調(diào)劑 +5 | 冬十三 2026-03-18 | 5/250 |
|
|
[考研] 296求調(diào)劑 +6 | www_q 2026-03-18 | 10/500 |
|
|
[考研] 工科材料085601 279求調(diào)劑 +7 | 困于星晨 2026-03-17 | 9/450 |
|
|
[考研] 復(fù)試調(diào)劑 +4 | z1z2z3879 2026-03-14 | 6/300 |
|
|
[考研] 化學(xué)工程321分求調(diào)劑 +15 | 大米飯! 2026-03-15 | 18/900 |
|
|
[考研]
|
胡辣湯放糖 2026-03-15 | 6/300 |
|
|
[考研] 考研化學(xué)學(xué)碩調(diào)劑,一志愿985 +4 | 張vvvv 2026-03-15 | 6/300 |
|
|
[考研] 一志愿南京大學(xué),080500材料科學(xué)與工程,調(diào)劑 +4 | Jy? 2026-03-16 | 4/200 |
|
|
[考研] 一志愿,福州大學(xué)材料專碩339分求調(diào)劑 +3 | 木子momo青爭 2026-03-15 | 3/150 |
|
|
[考研] 26考研一志愿中國石油大學(xué)(華東)305分求調(diào)劑 +3 | 嘉年新程 2026-03-15 | 3/150 |
|