類Unix流編輯器sed線上極速入門 第二部分
類Unix流編輯器sed線上極速入門 第二部分
sed 是十分強大和小巧的文字流編輯器。在本文章系列的第二部分中,將為您演示如何使用 sed 來執行字串替換、建立更大的 sed 指令碼以及如何使用 sed 的附加、插入和更改行命令。
sed 是很有用(但常被遺忘)的 UNIX 流編輯器。在以批處理方式編輯檔案或以有效方式建立 shell 指令碼來修改現有檔案方面,它是十分理想的工具。本文是 前一部分介紹 sed 文章的續篇。
替換!
讓我們看一下 sed 最有用的命令之一,替換命令。使用該命令,可以將特定字串或匹配的規則表示式用另一個字串替換。下面是該命令最基本用法的示例: 上面的命令將 myfile.txt 中每行第一次出現的 'foo'(如果有的話)用字串 'bar' 替換,然後將該檔案內容輸出到標準輸出。請注意,我說的是 每行第一次出現,儘管這通常不是您想要的。在進行字串替換時,通常想執行全域性替換。也就是說,要替換每行中的 所有出現,如下所示: 在最後一個斜槓之後附加的 'g' 選項告訴 sed 執行全域性替換。
關於 's///' 替換命令,還有其它幾件要了解的事。首先,它是一個命令,並且只是一個命令,在所有上例中都沒有指定地址。這意味著,'s///' 還可以與地址一起使用來控制要將命令應用到哪些行,如下所示: 上例將導致用短語 'entrapment' 替換所有出現的短語 'enchantment',但是隻在第一到第十行(包括這兩行)上這樣做。 該例將用 'mountains' 替換 'hills',但是,只從空行開始,到以三個字元 'END' 開始的行結束(包括這兩行)的文字塊上這樣做。
關於 's///' 命令的另一個妙處是 '/' 分隔符有許多替換選項。如果正在執行字串替換,並且規則表示式或替換字串中有許多斜槓,則可以透過在 's' 之後指定一個不同的字元來更改分隔符。例如,下例將把所有出現的 /usr/local 替換成 /usr: 在該例中,使用冒號作為分隔符。如果需要在規則表示式中指定分隔符字元,可以在它前面加入反斜槓。
規則表示式混亂
目前為止,我們只執行了簡單的字串替換。雖然這很方便,但是我們還可以匹配規則表示式。例如,以下 sed 命令將匹配從 '' 結束、並且在其中包含任意數量字元的短語。下例將刪除該短語(用空字串替換): 這是要從檔案除去 HTML 標記的第一個很好的 sed 指令碼嘗試,但是由於規則表示式的特有規則,它不會很好地工作。原因何在?當 sed 試圖在行中匹配規則表示式時,它要在行中查詢 最長的匹配。在前一部分中,這不成問題,因為我們使用的是 'd' 和 'p' 命令,這些命令總要刪除或列印整行。但是,在使用 's///' 命令時,確實有很大不同,因為規則表示式匹配的整個部分將被目標字串替換,或者,在本例中,被刪除。這意味著,上例將把下行: 變成:
我們要的不是這個,而是:
幸運的是,有一種簡便方法來糾正該問題。我們不輸入“'' 字元結束”的規則表示式,而只需輸入一個“'' 字元並以 '>' 字元結束”的規則表示式。這將與最短、而不是最長的可能性匹配。新命令如下: 在上例中,'[^>]' 指定“非 '>'”字元,其後的 '*' 完成該表示式以表示“零或多個非 '>' 字元”。對幾個 html 檔案測試該命令,將它們管道輸出到 "more",然後仔細檢視其結果。
更多字元匹配
'[ ]' 規則表示式語法還有一些附加選項。要指定字元範圍,只要字元不在第一個或最後一個位置,就可以使用 '-',如下所示:
這將匹配零或多個全部為 'a'、'b'、'c'...'v'、'w'、'x' 的字元。另外,可以使用 '[:space:]' 字元類來匹配空格。以下是可用字元類的相當完整的列表:
字元類 描述
[:alnum:] 字母數字 [a-z A-Z 0-9]
[:alpha:] 字母 [a-z A-Z]
[:blank:] 空格或製表鍵
[:cntrl:] 任何控制字元
[:digit:] 數字 [0-9]
[:graph:] 任何可視字元(無空格)
[:lower:] 小寫 [a-z]
[:print:] 非控制字元
[:punct:] 標點字元
[:space:] 空格
[:upper:] 大寫 [A-Z]
[:xdigit:] 十六進位制數字 [0-9 a-f A-F]
儘可能使用字元類是很有利的,因為它們可以更好地適應非英語 locale(包括某些必需的重音字元等等).
高階替換功能
我們已經看到如何執行簡單甚至有些複雜的直接替換,但是 sed 還可以做更多的事。實際上可以引用匹配規則表示式的部分或全部,並使用這些部分來構造替換字串。作為示例,假設您正在回覆一條訊息。下例將在每一行前面加上短語 "ralph said: ": 輸出如下:
該例的替換字串中使用了 '&' 字元,該字元告訴 sed 插入整個匹配的規則表示式。因此,可以將與 '.*' 匹配的任何內容(行中的零或多個字元的最大組或整行)插入到替換字串中的任何位置,甚至多次插入。這非常好,但 sed 甚至更強大。
那些極好的帶反斜槓的圓括號
's///' 命令甚至比 '&' 更好,它允許我們在規則表示式中定義 區域,然後可以在替換字串中引用這些特定區域。作為示例,假設有一個包含以下文字的檔案:
現在假設要編寫一個 sed 指令碼,該指令碼將把 "eeny meeny miny" 替換成 "Victor eeny-meeny Von miny" 等等。要這樣做,首先要編寫一個由空格分隔並與三個字串匹配的規則表示式。 現在,將在其中每個感興趣的區域兩邊插入帶反斜槓的圓括號來定義區域: 除了要定義三個可在替換字串中引用的邏輯區域以外,該規則表示式的工作原理將與第一個規則表示式相同。下面是最終指令碼: 如您所見,透過輸入 'x'(其中,x 是從 1 開始的區域號)來引用每個由圓括號定界的區域。輸入如下:
隨著對 sed 越來越熟悉,您可以花最小力氣來進行相當強大的文字處理。您可能想如何使用熟悉的指令碼語言來處理這種問題 -- 能用一行程式碼輕易實現這樣的解決方案嗎?
組合使用
在開始建立更復雜的 sed 指令碼時,需要有輸入多個命令的能力。有幾種方法這樣做。首先,可以在命令之間使用分號。例如,以下命令系列使用 '=' 命令和 'p' 命令,'=' 命令告訴 sed 列印行號,'p' 命令明確告訴 sed 列印該行(因為處於 '-n' 模式)。 無論什麼時候指定了兩個或更多命令,都按順序將每個命令應用到檔案的每一行。在上例中,首先將 '=' 命令應用到第 1 行,然後應用 'p' 命令。接著,sed 繼續處理第 2 行,並重復該過程。雖然分號很方便,但是在某些場合下,它不能正常工作。另一種替換方法是使用兩個 -e 選項來指定兩個不同的命令: 然而,在使用更為複雜的附加和插入命令時,甚至多個 '-e' 選項也不能幫我們的忙。對於複雜的多行指令碼,最好的方法是將命令放入一個單獨的檔案中。然後,用 -f 選項引用該指令碼檔案: 這種方法雖然可能不太方便,但總是管用。
一個地址的多個命令
有時,可能要指定應用到一個地址的多個命令。這在執行許多 's///' 以變換原始檔中的字和語法時特別方便。要對一個地址執行多個命令,可在檔案中輸入 sed 命令,然後使用 '{ }' 字元將這些命令分組,如下所示: 上例將把三個替換命令應用到第 1 行到第 20 行(包括這兩行)。還可以使用規則表示式地址或者二者的組合: 該例將把 '{ }' 之間的所有命令應用到從第 1 行開始,到以字母 "END" 開始的行結束(如果在原始檔中沒發現 "END",則到檔案結束)的所有行。
附加、插入和更改行
既然在單獨的檔案中編寫 sed 指令碼,我們可以利用附加、插入和更改行命令。這些命令將在當前行之後插入一行,在當前行之前插入一行,或者替換模式空間中的當前行。它們也可以用來將多行插入到輸出。插入行命令用法如下: 如果不為該命令指定地址,那麼它將應用到每一行,併產生如下的輸出:
如果要在當前行之前插入多行,可以透過在前一行之後附加一個反斜槓來新增附加行,如下所示: 附加命令的用法與之類似,但是它將把一行或多行插入到模式空間中的當前行之後。其用法如下: 另一方面,“更改行”命令將實際 替換模式空間中的當前行,其用法如下: 因為附加、插入和更改行命令需要在多行輸入,所以將把它們輸入到一個文字 sed 指令碼中,然後透過使用 '-f' 選項告訴 sed 執行它們。使用其它方法將命令傳遞給 sed 會出現問題。[@more@]
sed 是十分強大和小巧的文字流編輯器。在本文章系列的第二部分中,將為您演示如何使用 sed 來執行字串替換、建立更大的 sed 指令碼以及如何使用 sed 的附加、插入和更改行命令。
sed 是很有用(但常被遺忘)的 UNIX 流編輯器。在以批處理方式編輯檔案或以有效方式建立 shell 指令碼來修改現有檔案方面,它是十分理想的工具。本文是 前一部分介紹 sed 文章的續篇。
替換!
讓我們看一下 sed 最有用的命令之一,替換命令。使用該命令,可以將特定字串或匹配的規則表示式用另一個字串替換。下面是該命令最基本用法的示例: 上面的命令將 myfile.txt 中每行第一次出現的 'foo'(如果有的話)用字串 'bar' 替換,然後將該檔案內容輸出到標準輸出。請注意,我說的是 每行第一次出現,儘管這通常不是您想要的。在進行字串替換時,通常想執行全域性替換。也就是說,要替換每行中的 所有出現,如下所示: 在最後一個斜槓之後附加的 'g' 選項告訴 sed 執行全域性替換。
關於 's///' 替換命令,還有其它幾件要了解的事。首先,它是一個命令,並且只是一個命令,在所有上例中都沒有指定地址。這意味著,'s///' 還可以與地址一起使用來控制要將命令應用到哪些行,如下所示: 上例將導致用短語 'entrapment' 替換所有出現的短語 'enchantment',但是隻在第一到第十行(包括這兩行)上這樣做。 該例將用 'mountains' 替換 'hills',但是,只從空行開始,到以三個字元 'END' 開始的行結束(包括這兩行)的文字塊上這樣做。
關於 's///' 命令的另一個妙處是 '/' 分隔符有許多替換選項。如果正在執行字串替換,並且規則表示式或替換字串中有許多斜槓,則可以透過在 's' 之後指定一個不同的字元來更改分隔符。例如,下例將把所有出現的 /usr/local 替換成 /usr: 在該例中,使用冒號作為分隔符。如果需要在規則表示式中指定分隔符字元,可以在它前面加入反斜槓。
規則表示式混亂
目前為止,我們只執行了簡單的字串替換。雖然這很方便,但是我們還可以匹配規則表示式。例如,以下 sed 命令將匹配從 '' 結束、並且在其中包含任意數量字元的短語。下例將刪除該短語(用空字串替換): 這是要從檔案除去 HTML 標記的第一個很好的 sed 指令碼嘗試,但是由於規則表示式的特有規則,它不會很好地工作。原因何在?當 sed 試圖在行中匹配規則表示式時,它要在行中查詢 最長的匹配。在前一部分中,這不成問題,因為我們使用的是 'd' 和 'p' 命令,這些命令總要刪除或列印整行。但是,在使用 's///' 命令時,確實有很大不同,因為規則表示式匹配的整個部分將被目標字串替換,或者,在本例中,被刪除。這意味著,上例將把下行: 變成:
meant.
我們要的不是這個,而是:
This is what I meant.
幸運的是,有一種簡便方法來糾正該問題。我們不輸入“'' 字元結束”的規則表示式,而只需輸入一個“'' 字元並以 '>' 字元結束”的規則表示式。這將與最短、而不是最長的可能性匹配。新命令如下: 在上例中,'[^>]' 指定“非 '>'”字元,其後的 '*' 完成該表示式以表示“零或多個非 '>' 字元”。對幾個 html 檔案測試該命令,將它們管道輸出到 "more",然後仔細檢視其結果。
更多字元匹配
'[ ]' 規則表示式語法還有一些附加選項。要指定字元範圍,只要字元不在第一個或最後一個位置,就可以使用 '-',如下所示:
'[a-x]*'
這將匹配零或多個全部為 'a'、'b'、'c'...'v'、'w'、'x' 的字元。另外,可以使用 '[:space:]' 字元類來匹配空格。以下是可用字元類的相當完整的列表:
字元類 描述
[:alnum:] 字母數字 [a-z A-Z 0-9]
[:alpha:] 字母 [a-z A-Z]
[:blank:] 空格或製表鍵
[:cntrl:] 任何控制字元
[:digit:] 數字 [0-9]
[:graph:] 任何可視字元(無空格)
[:lower:] 小寫 [a-z]
[:print:] 非控制字元
[:punct:] 標點字元
[:space:] 空格
[:upper:] 大寫 [A-Z]
[:xdigit:] 十六進位制數字 [0-9 a-f A-F]
儘可能使用字元類是很有利的,因為它們可以更好地適應非英語 locale(包括某些必需的重音字元等等).
高階替換功能
我們已經看到如何執行簡單甚至有些複雜的直接替換,但是 sed 還可以做更多的事。實際上可以引用匹配規則表示式的部分或全部,並使用這些部分來構造替換字串。作為示例,假設您正在回覆一條訊息。下例將在每一行前面加上短語 "ralph said: ": 輸出如下:
ralph said: Hiya Jim, ralph said: ralph said:
I sure like this sed stuff! ralph said:
該例的替換字串中使用了 '&' 字元,該字元告訴 sed 插入整個匹配的規則表示式。因此,可以將與 '.*' 匹配的任何內容(行中的零或多個字元的最大組或整行)插入到替換字串中的任何位置,甚至多次插入。這非常好,但 sed 甚至更強大。
那些極好的帶反斜槓的圓括號
's///' 命令甚至比 '&' 更好,它允許我們在規則表示式中定義 區域,然後可以在替換字串中引用這些特定區域。作為示例,假設有一個包含以下文字的檔案:
foo bar oni eeny meeny miny larry curly moe jimmy the weasel
現在假設要編寫一個 sed 指令碼,該指令碼將把 "eeny meeny miny" 替換成 "Victor eeny-meeny Von miny" 等等。要這樣做,首先要編寫一個由空格分隔並與三個字串匹配的規則表示式。 現在,將在其中每個感興趣的區域兩邊插入帶反斜槓的圓括號來定義區域: 除了要定義三個可在替換字串中引用的邏輯區域以外,該規則表示式的工作原理將與第一個規則表示式相同。下面是最終指令碼: 如您所見,透過輸入 'x'(其中,x 是從 1 開始的區域號)來引用每個由圓括號定界的區域。輸入如下:
Victor foo-bar Von oni Victor eeny-meeny Von miny Victor larry-curly Von moe Victor jimmy-the Von weasel
隨著對 sed 越來越熟悉,您可以花最小力氣來進行相當強大的文字處理。您可能想如何使用熟悉的指令碼語言來處理這種問題 -- 能用一行程式碼輕易實現這樣的解決方案嗎?
組合使用
在開始建立更復雜的 sed 指令碼時,需要有輸入多個命令的能力。有幾種方法這樣做。首先,可以在命令之間使用分號。例如,以下命令系列使用 '=' 命令和 'p' 命令,'=' 命令告訴 sed 列印行號,'p' 命令明確告訴 sed 列印該行(因為處於 '-n' 模式)。 無論什麼時候指定了兩個或更多命令,都按順序將每個命令應用到檔案的每一行。在上例中,首先將 '=' 命令應用到第 1 行,然後應用 'p' 命令。接著,sed 繼續處理第 2 行,並重復該過程。雖然分號很方便,但是在某些場合下,它不能正常工作。另一種替換方法是使用兩個 -e 選項來指定兩個不同的命令: 然而,在使用更為複雜的附加和插入命令時,甚至多個 '-e' 選項也不能幫我們的忙。對於複雜的多行指令碼,最好的方法是將命令放入一個單獨的檔案中。然後,用 -f 選項引用該指令碼檔案: 這種方法雖然可能不太方便,但總是管用。
一個地址的多個命令
有時,可能要指定應用到一個地址的多個命令。這在執行許多 's///' 以變換原始檔中的字和語法時特別方便。要對一個地址執行多個命令,可在檔案中輸入 sed 命令,然後使用 '{ }' 字元將這些命令分組,如下所示: 上例將把三個替換命令應用到第 1 行到第 20 行(包括這兩行)。還可以使用規則表示式地址或者二者的組合: 該例將把 '{ }' 之間的所有命令應用到從第 1 行開始,到以字母 "END" 開始的行結束(如果在原始檔中沒發現 "END",則到檔案結束)的所有行。
附加、插入和更改行
既然在單獨的檔案中編寫 sed 指令碼,我們可以利用附加、插入和更改行命令。這些命令將在當前行之後插入一行,在當前行之前插入一行,或者替換模式空間中的當前行。它們也可以用來將多行插入到輸出。插入行命令用法如下: 如果不為該命令指定地址,那麼它將應用到每一行,併產生如下的輸出:
This line will be inserted before each line line 1 here
This line will be inserted before each line line 2 here
This line will be inserted before each line line 3 here
This line will be inserted before each line line 4 here
如果要在當前行之前插入多行,可以透過在前一行之後附加一個反斜槓來新增附加行,如下所示: 附加命令的用法與之類似,但是它將把一行或多行插入到模式空間中的當前行之後。其用法如下: 另一方面,“更改行”命令將實際 替換模式空間中的當前行,其用法如下: 因為附加、插入和更改行命令需要在多行輸入,所以將把它們輸入到一個文字 sed 指令碼中,然後透過使用 '-f' 選項告訴 sed 執行它們。使用其它方法將命令傳遞給 sed 會出現問題。[@more@]
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24790158/viewspace-1040129/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 類Unix流編輯器sed線上極速入門 第三部分
- 類Unix流編輯器sed線上極速入門 第一部分
- SED單行指令碼快速參考(Unix 流編輯器)指令碼
- VSCode編輯器極簡使用入門VSCode
- 詳解流編輯器 sed 和 程式語言 awk
- 文字處理流編輯器sed命令用法大全
- Mybatis極速入門MyBatis
- CMake極速入門
- WYSISYN編輯器 Prosemirror 入門ROS
- ES6極速入門
- Dagger 2 極速入門
- HTML線上編輯器HTML
- awk線上例項入門教程 第二部分
- Sublime Text:極速、靈活的程式碼編輯器Mac/Win版本Mac
- Html 文件線上編輯器HTML
- Unix vi編輯器命令總結
- 1 小時 SQL 極速入門(三)SQL
- 1 小時 SQL 極速入門(一)SQL
- 1 小時 SQL 極速入門(二)SQL
- vuex4 極速入門到上手Vue
- 線上富文字編輯器初探
- 線上HTML編輯器推薦HTML
- Klipped for Mac - 極簡文字編輯器Mac
- arcgis api for js入門開發系列十九圖層線上編輯APIJS
- flex.css快速入門,極速佈局FlexCSS
- Knative 初體驗:CICD 極速入門
- G6-Editor 編輯器入門使用教程
- sublimeText3編輯器 + 入門教程 + 使用大全
- 線上程式碼編輯器選型
- Unix類作業系統入門(轉)作業系統
- 程式碼線上編譯器(上)- 編輯及編譯編譯
- Go 語言極速入門4 - 物件導向Go物件
- Kubernetes(K8s)極速入門K8S
- 10個線上HTML程式碼編輯器HTML
- 編輯器之神VIM 總結 基礎部分
- Graviton:極簡的開原始碼編輯器原始碼
- 10分鐘極速入門dash應用開發
- 基於react的 markdown 輸入 + 即時預覽線上編輯器React