Sed字符串

本教程將介紹一些字符串處理的重要sed命令。考慮我們有一個文本文件books.txt 要處理,它有以下內容:

  1. A Storm of Swords, George R. R. Martin, 1216
  2. The Two Towers, J. R. R. Tolkien, 352
  3. The Alchemist, Paulo Coelho, 197
  4. The Fellowship of the Ring, J. R. R. Tolkien, 432
  5. The Pilgrimage, Paulo Coelho, 288
  6. A Game of Thrones, George R. R. Martin, 864

替換命令

「查找和替換」文本替換操作字符串最常見。下面給出的是替換命令的語法:

[address1[,address2]]s/pattern/replacement/[flags]

這裏,address1 和 address2分別是起始和結束地址,它可以是行號或模式串。這兩個地址是可選參數。

該模式是要替換的替換字符串的字符串。此外,也可以指定可選的標誌,以增強功能。

以下是 sed 命令替換所有books.txt 用逗號與豎線(|)。

[jerry]$ sed 's/,/ | /' books.txt

執行上面的代碼,得到如下結果:

  1. A Storm of Swords | George R. R. Martin, 1216
  2. The Two Towers | J. R. R. Tolkien, 352
  3. The Alchemist | Paulo Coelho, 197
  4. The Fellowship of the Ring | J. R. R. Tolkien, 432
  5. The Pilgrimage | Paulo Coelho, 288
  6. A Game of Thrones | George R. R. Martin, 864

如果仔細觀察,只有第一個逗號替換,第二保持原樣。爲什麼呢?只要模式匹配,Sed 替換爲替換字符串並且移動到下一行。默認情況下,它僅替換第一次出現。要替換所有出現的,使用Sed全局標誌(g)如下:

[jerry]$ sed 's/,/ | /g' books.txt

執行上面的代碼,得到如下結果:

  1. A Storm of Swords | George R. R. Martin | 1216
  2. The Two Towers | J. R. R. Tolkien | 352
  3. The Alchemist | Paulo Coelho | 197
  4. The Fellowship of the Ring | J. R. R. Tolkien | 432
  5. The Pilgrimage | Paulo Coelho | 288
  6. A Game of Thrones | George R. R. Martin | 864

可以指示Sed執行文本替換,只有當一個模式匹配成功。下面的示例替換逗號(,)用豎線(|)僅當行包含模式。

[jerry]$ sed '/The Pilgrimage/ s/,/ | /g' books.txt

執行上面的代碼,得到如下結果:

  1. A Storm of Swords, George R. R. Martin, 1216
  2. The Two Towers, J. R. R. Tolkien, 352
  3. The Alchemist, Paulo Coelho, 197
  4. The Fellowship of the Ring, J. R. R. Tolkien, 432
  5. The Pilgrimage | Paulo Coelho | 288
  6. A Game of Thrones, George R. R. Martin, 864

Sed 也可以取代的模式發生的特定事件。替換逗號(,)以豎線的唯一的第二個實例(|)。下面是在sed命令(或標誌的地方),當前匹配的第二個出現的有多少。

[jerry]$ sed 's/,/ | /2' books.txt

執行上面的代碼,得到如下結果:

  1. A Storm of Swords, George R. R. Martin | 1216
  2. The Two Towers, J. R. R. Tolkien | 352
  3. The Alchemist, Paulo Coelho | 197
  4. The Fellowship of the Ring, J. R. R. Tolkien | 432
  5. The Pilgrimage,Paulo Coelho | 288
  6. A Game of Thrones, George R. R. Martin | 864

可以使用P標誌,如下打印不僅改變的行:

[jerry]$ sed -n 's/Paulo Coelho/PAULO COELHO/p' books.txt

執行上面的代碼,得到如下結果:

  1. The Alchemist, PAULO COELHO, 197
  2. The Pilgrimage, PAULO COELHO, 288

可以在另一個文件中保存更改的行。爲了實現這種結果,可以使用 w 標誌如下所示:

[jerry]$ sed -n 's/Paulo Coelho/PAULO COELHO/w junk.txt' books.txt

現在 junk.txt 文件已全部更改的文件。讓我們驗證 junk.txt 文件的內容。

[jerry]$ cat junk.txt

執行上面的代碼,得到如下結果:

  1. The Alchemist, PAULO COELHO, 197
  2. The Pilgrimage, PAULO COELHO, 288

執行不區分大小寫的替換,可以使用i標誌,這意味着忽略大小寫。下面的例子執行不區分大小寫的替換。

[jerry]$ sed -n 's/pAuLo CoElHo/PAULO COELHO/pi' books.txt

執行上面的代碼,得到如下結果:

  1. The Alchemist, PAULO COELHO, 197
  2. The Pilgrimage, PAULO COELHO, 288

非標分隔符

通常,反斜槓(/)作爲分隔符,但有時是用其它支持定界符以用 sed 更方便。

到目前爲止,我們已經使用了只有反斜槓(/)字符作爲分隔符,但我們也可以使用豎線(|),at符號(@),插入符號(^),感嘆號作爲分隔符(!)。下面的示例演示瞭如何使用其他字符作爲分隔符。

下面的例子使用豎線(|)作爲分隔符:

[jerry]$ echo "/bin/sed" | sed 's|/bin/sed|/home/jerry/src/sed/sed-4.2.2/sed|'

執行上面的代碼,得到如下結果:

/home/jerry/src/sed/sed-4.2.2/sed

同樣,我們可以用「at」符號(@)使用作爲分隔符,如下所示:

[jerry]$ echo "/bin/sed" | sed 's@/bin/sed@/home/jerry/src/sed/sed-4.2.2/sed@'

執行上面的代碼,得到如下結果:

/home/jerry/src/sed/sed-4.2.2/sed

同樣,我們可以使用插入符號(^)作爲分隔符,如下所示:

[jerry]$ echo "/bin/sed" | sed 's^/bin/sed^/home/jerry/src/sed/sed-4.2.2/sed^'

執行上面的代碼,得到如下結果:

/home/jerry/src/sed/sed-4.2.2/sed

同樣,我們可以使用感嘆號作爲分隔符如下(!):

[jerry]$ echo "/bin/sed" | sed 's!/bin/sed!/home/jerry/src/sed/sed-4.2.2/sed!'

執行上面的代碼,得到如下結果:

/home/jerry/src/sed/sed-4.2.2/sed

創建一個子串

我們學到了強大的替換命令。看看是否可以找到一個匹配的文本字符串。瞭解如何用一個例子來說明。

看看下面的文字:

[jerry]$ echo "Three One Two"

假設我們要安排成一個序列。意味着,它應該打印一份,再兩個,最後三個。下面的單行代碼執行。

[jerry]$ echo "Three One Two" | sed 's|\(\w\+\) \(\w\+\) \(\w\+\)|\2 \3 \1|'

sed 子串可以通過使用分組操作員指定,並且它必須以轉義字符作爲前綴,即\(和\)。

在這裏,\ w是一個正則表達式匹配任何字母或下劃線和「+」號來匹配多個字符。換句話說,正則表達式 \(\w\+\)從輸入串中的單個字相匹配。

這個子串由\N,N是子串號轉介。因此,\2打印第二子串,即一個; \3打印第三子串,即兩種;和\1打印第一子,即Three

讓我們分開這些話通過逗號(,)並相應修改則表達式。

[jerry]$ echo "Three,One,Two" | sed 's|\(\w\+\),\(\w\+\),\(\w\+\)|\2,\3,\1|'

執行上面的代碼,得到如下結果:

One,Two,Three

字符串替換標誌

GNU Sed 提供可在替換字符串中使用一些特殊的轉義序列。請注意,這些字符串替換標誌是GNU具體指定,可能無法與Sed其他變種進行工作。在這裏,我們將討論的字符串替換標誌。

 \L 標識

當在替換字符串中指定\L,它把該單詞的所有剩餘的字符,\L以小寫字符。例如,字符「ULO」被視爲小寫字符。

[jerry]$ sed -n 's/Paulo/PA\LULO/p' books.txt

執行上面的代碼,得到如下結果:

  1. The Alchemist, PAulo Coelho, 197
  2. The Pilgrimage, PAulo Coelho, 288

\u 標識

\u被替換字符串指定,它把後\u,如大寫字符前的字符。在下面的例子中,\u字符爲'a'和'o'之前使用。因此,Sed將這些字符轉爲大寫字母。

[jerry]$ sed -n 's/Paulo/p\uaul\uo/p' books.txt

執行上面的代碼,得到如下結果:

  1. The Alchemist, pAulO Coelho, 197
  2. The Pilgrimage, pAulO Coelho, 288

\U 標識

當\U在替換字符串中指定,把單詞的所有剩餘的字符\U後爲大寫字母。

[jerry]$ sed -n 's/Paulo/\Upaulo/p' books.txt

執行上面的代碼,得到如下結果:

  1. The Alchemist, PAULO Coelho, 197
  2. The Pilgrimage, PAULO Coelho, 288

 \E 標識

\E標誌應使用\L或\U。它標誌\L或\U開始停止轉換。在下面的例子中,只有第一個字被替換爲大寫字母。

[jerry]$ sed -n 's/Paulo Coelho/\Upaulo \Ecoelho/p' books.txt

執行上面的代碼,得到如下結果:

  1. The Alchemist, PAULO coelho, 197
  2. The Pilgrimage, PAULO coelho, 288