• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Prayer

            在一般中尋求卓越
            posts - 1256, comments - 190, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            sed學(xué)習(xí)筆記二--高級(jí)命令

            Posted on 2010-09-15 10:33 Prayer 閱讀(1583) 評(píng)論(0)  編輯 收藏 引用 所屬分類: Shell
            版權(quán)聲明:原創(chuàng)作品,允許轉(zhuǎn)載,轉(zhuǎn)載時(shí)請(qǐng)務(wù)必以超鏈接形式標(biāo)明文章 原始出處 、作者信息和本聲明。否則將追究法律責(zé)任。http://licong.blog.51cto.com/542131/204226
            之前寫過一篇《sed學(xué)習(xí)筆記》http://licong.blog.51cto.com/542131/152541,講了一點(diǎn)sed入門的東西,本篇將繼續(xù)介紹sed高級(jí)命令部分。所謂高級(jí),主要是指這里將要提到的命令都能改變sed執(zhí)行或者控制的流程順序(sed通常都是一行被讀入模式空間,并用腳本中的sed命令一個(gè)接一個(gè)的應(yīng)用于那一行) 

            高級(jí)sed命令分成3個(gè)組:

            1、    處理多行模式空間(NDP)。

            2、    采用保持空間來保存模式空間的內(nèi)容并使他們可用于后續(xù)的命令(HhGgx)。

            3、    編寫使用分支和條件指令的腳本來更改控制流(:、bt)。 

            N命令:追加下一行
            多行Next(N)命令通過讀取當(dāng)前行的下一行,并把兩行拼成一行來進(jìn)行接下來的處理。
            $ cat file
            line 1
            line 2
            line 3
            line 4
            file文件中的每一行后面都有一個(gè)隱藏的換行符”\n”sed不對(duì)每行末尾的”\n”進(jìn)行處理。
            $ sed N file
            line 1
            line 2
            line 3
            line 4
            經(jīng)過N處理過的輸出和原文件沒有區(qū)別,但是本質(zhì)是不一樣的。這里sed其實(shí)認(rèn)為自己打印的是2行,第一行為”line 1\nline 2”,而第2行為”line 3\nline 4”,注意這里的2行末尾依然隱藏?fù)Q行符”\n”sed依然不處理行尾的”\n”,但是處理行內(nèi)的”\n”。因?yàn)檫@里默認(rèn)的動(dòng)作是打印,所以處理行內(nèi)的”\n”我們也看不出來。
            值得注意的是,處理line 1時(shí),line 2被讀入并追加到line 1后面,所以line 1處理完后不再讀入line 2(前面已經(jīng)讀過了)而直接讀入line 3進(jìn)行下一個(gè)N命令(即讀入line 4并追加到line 3后面)。
            上面2段如果不理解的話,看下面這個(gè)命令:
            $ sed ‘N;s/\n/ /g’ file
            line 1 line 2
            line 3 lin3 4
            這個(gè)命令在原來的基礎(chǔ)上把行內(nèi)的”\n”替換成空格了(盡管用了全局替換標(biāo)志gsed依然不處理行尾換行符!),看明白N的作用了嗎,單獨(dú)的N可以創(chuàng)建2行模式空間。 
            D命令:刪除多行模式空間中,直到第一個(gè)行內(nèi)的”\n”為止的所有內(nèi)容。
            D命令通常位于N命令之后,用于處理N命令創(chuàng)建的多行模式空間。D命令刪除多行模式空間行內(nèi)第一個(gè)”\n”及其之前的內(nèi)容后,對(duì)余下的內(nèi)容(第一個(gè)行內(nèi)”\n”之后的內(nèi)容)重新從sed第一個(gè)命令進(jìn)行處理。

            Dd的相同點(diǎn)是,刪除內(nèi)容后,重新從sed第一個(gè)命令開始處理,這一點(diǎn)看來Dd都有改變sed執(zhí)行順序的能力;區(qū)別在于d刪除模式空間中的所有內(nèi)容,然后重新讀取文本下一行從sed頂部進(jìn)行處理,而D刪除模式空間的一部分內(nèi)容,而將模式空間剩下的內(nèi)容從sed頂部進(jìn)行處理。
            $ sed ‘N;d’ file
            $
            $sed ‘N;D’ file
            line 4
            ‘N;d’每次創(chuàng)建2行模式空間,并將模式空間的內(nèi)容全部刪除,所以結(jié)果所有4行(sed看來是2行)都刪除了。如果file5行數(shù)據(jù),則第5行將被打印出來,因?yàn)榈?/span>5行執(zhí)行N時(shí)讀不到下一行了,所以d不執(zhí)行,打印第5行,你可以自己試一試。
            ‘N;D’每次創(chuàng)建2行模式空間,刪除前面一行,并將模式空間的第2行繼續(xù)執(zhí)行’N;D’,直到最后一行N沒內(nèi)容可讀,不執(zhí)行D,而是打印最后一行。’N;D’實(shí)際構(gòu)成了一個(gè)循環(huán)(想想N直接讀入下一行,對(duì)2行進(jìn)行處理,下一次對(duì)第2行就不處理了而是讀取第3行處理;而加了D之后,先處理2行,再對(duì)剩下的第2行接著進(jìn)行處理) 
            P命令:打印模式空間直到第一個(gè)”\n”為止的所有內(nèi)容。
            p(小寫)是打印模式空間的所有內(nèi)容,P(大寫)是打印模式空間的一部分,這一區(qū)別和D/d類似。有一點(diǎn)要注意,不要把任何命令放在d或者D后面,因?yàn)槟菢釉撁钣肋h(yuǎn)也沒有執(zhí)行的機(jī)會(huì)了。例如sed ‘N;D;P’ filesed ‘N;D’ file是完全相同的效果。
            $ cat file
            line 1 li
            cong line 2
            line 3 licong
            line 4 li
            cong line 5
            我們要把分在兩行的licong合到一行應(yīng)該怎么做呢?
            $ sed 'N;s/li\ncong */licong\n/g;P;D' file
            line 1 licong
            line 2
            line 3 licong
            line 4 licong
            line 5
            執(zhí)行這個(gè)sed命令的流程是這樣的:
            一、首行文本應(yīng)用N讀取下一行,構(gòu)成2行模式空間
            line 1 li\n
            cong line 2
            s命令將li\ncong (注意cong后有一個(gè)空格)替換成licong\n,
            line 1 licong
            line 2
            接著執(zhí)行P,打印line 1 licongP結(jié)束后兩行模式空間沒有改變)
            再對(duì)兩行模式空間執(zhí)行D,刪除line 1 licong\n,并將剩下的line 2做為新的模式空間從頭執(zhí)行sed命令;
            二、對(duì)模式空間內(nèi)容line 2先執(zhí)行N,讀取下一行line 3 licong,創(chuàng)建兩行模式空間
            line 2
            line 3 licong
            這次s沒找到匹配內(nèi)容,所以執(zhí)行s后面的P;D命令,重新打印、刪除,進(jìn)行下一輪循環(huán);
            。。。
            三、最后一行line 5執(zhí)行N沒有內(nèi)容可讀,直接打印該行。
             
            hHgGx這幾個(gè)命令都是用于模式空間和保持空間轉(zhuǎn)換的。這里有必要解釋一下模式空間和保持空間了:
            模式空間——容納當(dāng)前輸入行的緩沖區(qū)。
            除了h/H/g/G/x,其他所有sed命令都是針對(duì)模式空間的內(nèi)容進(jìn)行處理的!
            保持空間——模式空間以外的一個(gè)預(yù)留緩沖區(qū)。
            只有h/H/g/G/x命令可以訪問到保持空間的內(nèi)容,并用于與模式空間內(nèi)容的轉(zhuǎn)換。

            h:將模式空間的內(nèi)容復(fù)制到保持空間,類似與重定向符號(hào)>,會(huì)覆蓋原由保持空間內(nèi)容
            H:將模式空間的內(nèi)容追加到保持空間,類似與追加重定向>>,追加到保持空間的尾行下
            g:類似h,將保持空間的內(nèi)容復(fù)制到模式空間
            G:類似H,將保持空間的內(nèi)容追加到模式空間
            x:交換模式空間與保持空間中的內(nèi)容 

            $ cat file
            1
            2
            11
            22
            $ sed ‘/1/{h;d};/2/G’ file
            2
            1
            22
            11
            這個(gè)sed命令完成了反轉(zhuǎn)的功能,我們來看看是怎么實(shí)現(xiàn)的:
            一、/1/{h;d}命令搜索模式空間包含1的行然后先后執(zhí)行hd命令。結(jié)果首行1將被應(yīng)用,h把該行(內(nèi)容為1)復(fù)制到保持空間,此時(shí)模式空間和保持空間中的內(nèi)容為:
            模式空間:1
            保持空間:1
            接著執(zhí)行dd不能訪問保持空間,只處理模式空間的內(nèi)容,將模式空間的內(nèi)容刪除,此時(shí):
            模式空間:      (空,沒有內(nèi)容)
            保持空間:1
            二、d命令執(zhí)行完之后,執(zhí)行/2/G,即在模式空間搜索包含2的行進(jìn)行G處理,而此時(shí)模式空間無內(nèi)容,所以不做任何操作。
            三、讀取下一行文本到模式空間,繼續(xù)執(zhí)行’/1/{h;d};/2/G’。下一行文本的內(nèi)容是2,此時(shí):
            模式空間:2
            保持空間:1
            與步驟二的道理相同,hd得不到執(zhí)行(因?yàn)槟J娇煽臻g沒找到包含1的行);而’/2/G’將被執(zhí)行,將保持空間的內(nèi)容追加到模式空間后面,此時(shí):
            模式空間:2
                     1
            保持空間:1
            這一步完成以后,模式空間的內(nèi)容將被sed默認(rèn)地打印出來(如果有-n參數(shù)才不打印),于是前兩行處理完之后,將輸出:
            2
            1

            同理,后兩行處理完之后,將輸出:
            22
            11
            于是,我們看到了最后的結(jié)果:
            2
            1
            22
            11 
            這個(gè)最簡單的例子有很多地方值得挖掘,我們就來看看最重要的幾點(diǎn)。

            1、 當(dāng)sed后面帶有一個(gè)以上的命令時(shí),它的處理順序是這樣的:

            一次讀入一行到模式空間,然后將所有的命令應(yīng)用于該行;而不是一次將一個(gè)命令作用與所有行;

            2、 當(dāng)某個(gè)條件后面有{}時(shí),{}里面的命令依次作用于滿足該條件的行;

            3、 h/H/g/G命令操作緩沖區(qū)時(shí),都會(huì)在目的緩沖區(qū)后加一個(gè)換行(即使該緩沖區(qū)無內(nèi)容),然后復(fù)制或追加源緩沖區(qū)內(nèi)容在該換行符之后;

            4、 沒有使用-n參數(shù)時(shí),當(dāng)一行執(zhí)行完所有命令后,sed會(huì)默認(rèn)打印最終模式空間中的內(nèi)容;

            如果使用-n參數(shù),只有應(yīng)用了p/P命令的模式空間內(nèi)容才會(huì)被打印出來。


            x命令暫不舉例,我們來看看最后一組高級(jí)命令(:、bt
            分支(b)和測(cè)試(t)命令幾乎可以任意改變sed命令的執(zhí)行順序,他們都將sed轉(zhuǎn)移到包含標(biāo)簽的行,如果沒有指定標(biāo)簽,則將轉(zhuǎn)移到命令末尾。b用于無條件的轉(zhuǎn)移(即一碰到b立刻轉(zhuǎn)移);t用于有條件轉(zhuǎn)移,只有當(dāng)替換命令改變當(dāng)前行時(shí)才會(huì)執(zhí)行。 
            標(biāo)簽定義:
            :lable
            lable可以隨便用什么名字,自己能方便看明白就行;冒號(hào)和標(biāo)簽之間不允許有空格,lable后面如果有空格將被認(rèn)為是lable的一部分(不建議在lable后面帶空格)
            bt的用法:
            [address]b [lable]
            [address]t [lable]
            b/tlable之間有空格,但lable后面不要插入空格。
            舉例:
            $ cat file
            line 1 li
            cong line 2
            line 3 licong
            line 4 li
            cong line 5 

            $ sed -n '$!{/licong/!{h;N;D}
            x;G;N;p;b
            }
            ${/licong/{x;G;p}}' file
            cong line 2
            line 3 licong
            line 4 li 
            這個(gè)sed命令的功能是尋找包含字符串licong的行,并打印該行及其前后一行。這個(gè)命令并不完善,它不能很好的處理第一行匹配的情況,加入該功能命令會(huì)變得更復(fù)雜。我們來解釋一下上面的結(jié)果是怎么來的。
            一、sed -n '$!{/licong/!{h;N;D}
            x;G;N;p;b
            對(duì)除末行以外的所有行($!的作用),執(zhí)行/licong/!{h;N;D}x;G;N;p;b
            二、/licong/!{h;N;D}
            對(duì)不包含字符串licong的行依次執(zhí)行hND,第一行line 1 li不包含licong,于是執(zhí)行:
            把該行復(fù)制到保持空間,讀取追加下一行,此時(shí)
            模式空間:line 1 li
            cong line 2
            保持空間:line 1 li
            再對(duì)模式空間執(zhí)行D,并接著從頭處理新的模式空間,此時(shí)
            模式空間:cong line 2
            保持空間:line 1 li
            三、從頭對(duì)模式空間的內(nèi)容cong line 2執(zhí)行$!{/licong/!{h;N;D},此時(shí)的模式空間依然不包含licong,所以進(jìn)行一二兩步同樣的操作,結(jié)束后:
            模式空間:line 3 licong
            保持空間:cong line 2
            四、再從頭對(duì)新的模式空間line 3 licong執(zhí)行/licong/!{h;N;D}x;G;N;p;b。因?yàn)榇藭r(shí)的模式空間包含licong,所以不執(zhí)行h;N;D了,而是執(zhí)行x;G;N;p;bx用與交換模式空間和保持空間的內(nèi)容,交換的結(jié)果是:

            模式空間:cong line 2
            保持空間:line 3 licong

            接下來執(zhí)行G,將保持空間的內(nèi)容追加到模式空間之后:

             模式空間:cong line 2
                       line 3 licong
            保持空間:line 3 licong

            再執(zhí)行N,將下一行讀取追加到模式空間之后:

             模式空間:cong line 2
            line 3 licong
                                line 4 li
            保持空間:line 3 licong
            再執(zhí)行p,打印模式空間的內(nèi)容:
            cong line 2
                line 3 licong
                   line 4 li            (這就是我們看到的結(jié)果)
            之后還有一個(gè)b,就是跳過b后面的命令,再讀下一行。命令最后一部分${/licong/{x;G;p}}是用來處理最后一行的,如果最后一行包含licong則打印該行很上面一行(而不打印下一行,因?yàn)闆]有N命令)

            到此,sed的高級(jí)命令就介紹完了。《sed&awk》第二版有一句話:“一旦你理解了這里所給出的命令,那么就可以認(rèn)為自己是真正的sed的主人了。”
            再總結(jié)一下sed所有的功能,總的來說還是替換命令’[address]s/source/replace/flag’最常用,而高級(jí)命令則用于完成復(fù)雜的任務(wù);還有sed-n(抑制默認(rèn)輸出)、-i(更改原文件)等參數(shù)也很常用。 
            就寫到這里吧,等待拍磚了。。。

            本文出自 “licong” 博客,請(qǐng)務(wù)必保留此出處http://licong.blog.51cto.com/542131/204226

            本文出自 51CTO.COM技術(shù)博客
            国产精品美女久久福利网站| 久久精品国产72国产精福利| 久久天天躁狠狠躁夜夜2020老熟妇 | 亚洲精品国精品久久99热一| 欧美久久天天综合香蕉伊| 蜜桃麻豆www久久| 国产精品一区二区久久精品| 99久久婷婷国产综合亚洲| 日产精品久久久久久久性色| 无码AV波多野结衣久久| 伊人久久大香线蕉亚洲五月天| 2020国产成人久久精品| 精品熟女少妇AV免费久久| 无码AV中文字幕久久专区| 69久久夜色精品国产69| 青青草原综合久久| 久久黄视频| 精品久久亚洲中文无码| 日本久久久久亚洲中字幕 | 99久久精品午夜一区二区| 精品熟女少妇av免费久久| 996久久国产精品线观看| 嫩草影院久久99| 久久无码一区二区三区少妇| 久久精品国产亚洲AV不卡| 99久久精品国产高清一区二区 | 久久久久九国产精品| 一本久久精品一区二区| 久久久久高潮综合影院| 久久99国产亚洲高清观看首页| 久久国产精品国语对白| 久久精品国产男包| 日本精品久久久久中文字幕| 中文成人无码精品久久久不卡 | 99热成人精品免费久久| 亚洲一级Av无码毛片久久精品| 久久亚洲私人国产精品vA| 国产精品久久久久久久久久免费| 狠狠色丁香婷婷久久综合五月| 久久精品视频网| 日韩精品久久久肉伦网站|