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
執行上麵的代碼,得到如下結果:
3) The Alchemist, PAULO COELHO, 197 5) 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
執行上麵的代碼,得到如下結果:
3) The Alchemist, PAULO COELHO, 197 5) The Pilgrimage, PAULO COELHO, 288
執行不區分大小寫的替換,可以使用i標誌,這意味著忽略大小寫。下麵的例子執行不區分大小寫的替換。
[jerry]$ sed -n 's/pAuLo CoElHo/PAULO COELHO/pi' books.txt
執行上麵的代碼,得到如下結果:
3) The Alchemist, PAULO COELHO, 197 5) 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
執行上麵的代碼,得到如下結果:
3) The Alchemist, PAulo Coelho, 197 5) The Pilgrimage, PAulo Coelho, 288
\u 標識
\u被替換字符串指定,它把後\u,如大寫字符前的字符。在下麵的例子中,\u字符為'a'和'o'之前使用。因此,Sed將這些字符轉為大寫字母。
[jerry]$ sed -n 's/Paulo/p\uaul\uo/p' books.txt
執行上麵的代碼,得到如下結果:
3) The Alchemist, pAulO Coelho, 197 5) The Pilgrimage, pAulO Coelho, 288
\U 標識
當\U在替換字符串中指定,把單詞的所有剩餘的字符\U後為大寫字母。
[jerry]$ sed -n 's/Paulo/\Upaulo/p' books.txt
執行上麵的代碼,得到如下結果:
3) The Alchemist, PAULO Coelho, 197 5) The Pilgrimage, PAULO Coelho, 288
\E 標識
\E標誌應使用\L或\U。它標誌\L或\U開始停止轉換。在下麵的例子中,隻有第一個字被替換為大寫字母。
[jerry]$ sed -n 's/Paulo Coelho/\Upaulo \Ecoelho/p' books.txt
執行上麵的代碼,得到如下結果:
3) The Alchemist, PAULO coelho, 197 5) The Pilgrimage, PAULO coelho, 288