91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

sed4.4手冊

發布時間:2020-08-08 10:26:07 來源:ITPUB博客 閱讀:149 作者:85579711 欄目:建站服務器

sed,流編輯器

目錄

  • 1簡介
  • 2運行sed
    • 2.1概述
    • 2.2命令行選項
    • 2.3退出狀態
  • 3sed腳本
    • 3.1 sed腳本概述
    • 3.2 sed命令摘要
    • 3.3 s命令
    • 3.4常用命令
    • 3.5較少使用的命令
    • 3.6 sed大師命令
    • 3.7特定于GNU的命令 sed
    • 3.8多種命令語法
      • 3.8.1需要換行符的命令
  • 4地址:選擇行
    • 4.1地址概述
    • 4.2按數字選擇行
    • 4.3通過文本匹配選擇行
    • 4.4范圍地址
  • 5正則表達式:選擇文本
    • 5.1正則表達式概述 sed
    • 5.2基本(BRE)和擴展(ERE)正則表達式
    • 5.3基本正則表達式語法概述
    • 5.4擴展正則表達式語法概述
    • 5.5字符類和括號表達式
    • 5.6正則表達式擴展
    • 5.7反向引用和子表達式
    • 5.8轉義序列 - 指定特殊字符
    • 5.9語言環境注意事項
  • 6高級sed:循環和緩沖區
    • 6.1 sed工作原理
    • 6.2保持和模式緩沖區
    • 6.3多線技術 - 使用D,G,H,N,P來處理多條線
    • 6.4分支和流量控制
      • 6.4.1分支和周期
      • 6.4.2分支示例:連線
  • 7一些示例腳本
    • 7.1連線
    • 7.2中心線
    • 7.3增加數字
    • 7.4將文件重命名為小寫
    • 7.5打印bash環境
    • 7.6線的反轉字符
    • 7.7跨多行的文本搜索
    • 7.8線長調整
    • 7.9文件的反向行
    • 7.10編號
    • 7.11編號非空行
    • 7.12計數字符
    • 7.13計數單詞
    • 7.14計數線
    • 7.15打印第一行
    • 7.16打印最后一行
    • 7.17使重復行獨特
    • 7.18打印輸入的重復行
    • 7.19刪除所有重復的行
    • 7.20擠壓空白線
  • GNU sed的限制和不受限制
  • 9其他資源學習關于 sed
  • 10報告錯誤
  • 附錄A GNU自由文件許可證
  • 概念指數
  • 命令和選項索引

GNU sed

該文件記錄GNU 版本4.4 sed,一個流編輯器。

版權所有©1998-2017自由軟件基金會

授權根據GNU自由文件許可證1.3版或自由軟件基金會發布的任何更新版本的條款復制,分發和/或修改本文檔; 沒有不變的部分,沒有封面文本,也沒有封底文本。許可證的副本包含在題為“GNU自由文件許可證”的部分。


1簡介

sed是一個流編輯器。流編輯器用于對輸入流(文件或流水線的輸入)執行基本文本轉換。雖然在某些方面類似于允許腳本編輯(例如ed) 的編輯器,sed只能通過輸入一次,但效率更高。但是,它有sed能力在管道中過濾文本,特別區別于其他類型的編輯器。



2運行sed

本章介紹如何運行sedsed 腳本和單個sed命令的詳細信息將在下一章討論。


2.1概述

通常sed被這樣調用:

sed SCRIPT INPUTFILE ... 

例如,要取代所有出現的“你好' 至 '世界'在文件中 input.txt中

sed / s / hello / world /'input.txt> output.txt 

如果不指定INPUTFILE,或者如果INPUTFILE - , sed過濾標準輸入的內容。以下命令是等效的:

sed / s / hello / world /'input.txt> output.txt  sed's / hello / world /' output.txt  cat input.txt | sed / s / hello / world /' - > output.txt 

sed將輸出寫入標準輸出。使用-一世在現場編輯文件而不是打印到標準輸出。又見Ws///w寫入輸出到其它文件的命令。以下命令修改file.txt的 并且不產生任何輸出:

sed -i / hello / world'file.txt 

默認情況下sed打印所有已處理的輸入(除了通過命令修改/刪除的輸入d)。使用-n抑制輸出,以及p打印特定行命令。以下命令僅打印輸入文件的第45行:

sed -n'45p'file.txt 

sed將多個輸入文件視為一個長流。以下示例打印第一個文件的第一行(此時就把one.txt存盤)和最后一個文件的最后一行(three.txt)。使用-s 以扭轉這種行為。

sed -n'1p; $ p'one.txt two.txt three.txt 

沒有 -e 要么 -F選項,sed使用第一個非選項參數作為腳本,以及以下非選項參數作為輸入文件。如果-e 要么 -F選項用于指定腳本,所有非選項參數均作為輸入文件。選項-e和 -F可以組合,并且可以出現多次(在這種情況下,最終的有效腳本將連接所有單個腳本)。

以下示例是等效的:

sed'/ hello / world /'input.txt> output.txt   sed -e's / hello / world  /'input.txt > output.txt sed --expression ='s / hello / world /'input.txt > output.txt   echo's / hello / world /'> myscript.sed  sed -f myscript.sed input.txt> output.txt  sed --file = myscript.sed input.txt> output.txt 

2.2命令行選項

調用的完整格式sed是:

sed選項... [SCRIPT] [INPUTFILE ...] 

sed 可以使用以下命令行選項調用:

--version

打印sed正在運行的版本和版權聲明,然后退出。

--help

打印使用消息,簡要總結這些命令行選項和錯誤報告地址,然后退出。

-n --quiet --silent

默認情況下,sed通過腳本在每個循環結束時打印出圖案空間(請參閱如何sed工作)。這些選項禁用此自動打印,并且sed僅在通過p命令明確告知時才產生輸出

-e script --expression=script

腳本中的命令添加到要處理輸入時要運行的命令集。

-f script-file --file=script-file

將文件腳本文件中包含的命令添加 到要處理輸入時要運行的命令集。

-i[SUFFIX] --in-place[=SUFFIX]

此選項指定要在現場編輯文件。 GNU sed通過創建臨時文件并將輸出發送到此文件而不是標準輸出。1

這個選項意味著 -s

當文件結束到達時,臨時文件將重命名為輸出文件的原始名稱。擴展名(如果提供)用于在重命名臨時文件之前修改舊文件的名稱,從而備份副本2)。


該規則遵循:如果擴展名不包含a *,則作為后綴添加到當前文件名的末尾; 如果擴展名包含一個或多個* 字符,則每個星號將替換為當前文件名。這允許您為備份文件添加前綴,而不是(或除了)后綴,甚至將原始文件的備份副本放置到另一個目錄中(如果目錄已存在)。

如果沒有提供擴展名,原始文件將被覆蓋而不進行備份。

-l N --line-length=N

指定命令的默認換行長度l長度為零(零)意味著永遠不要纏繞長線。如果未指定,則取為70。

--posix

GNU sed包括POSIX sed的幾個擴展名為了簡化寫入便攜式腳本,此選項將禁用此手冊所有文檔的擴展名,包括其他命令。 大多數擴展sed程序都接受POSIX所規定的語法之外的程序,但其中一些(例如Reporting Bugs中N描述命令的行為)實際上違反了標準。如果要僅禁用后一種擴展名,則可以將該變量設置為非空值。 POSIXLY_CORRECT

-b --binary

此選項在每個平臺上可用,但僅在操作系統區分文本文件和二進制文件之間才有效。當進行這樣的區分時,如MS-DOS,Windows的情況,Cygwin文本文件由由回車符換行字符分隔的行組成 ,并且sed看不到結尾的CR。當指定此選項時,sed將以二進制模式打開輸入文件,因此不要求此特殊處理,并考慮以行結尾的行。

--follow-symlinks

此選項僅在支持符號鏈接的平臺上可用,并且僅在選項時才有效果 -一世 被指定。在這種情況下,如果在命令行中指定的文件是符號鏈接,sed則將跟隨鏈接并編輯鏈接的最終目的地。默認行為是中斷符號鏈接,以使鏈接目的地不被修改。

-E -r --regexp-extended

使用擴展正則表達式而不是基本正則表達式。擴展的正則表達式是那些 egrep接受的; 它們可以更清晰,因為它們通常具有較少的反斜杠。歷史上這是一個GNU擴展,但是-E 擴展已經被添加到POSIX標準(http://austingroupbugs.net/view.php?id=528),所以使用 -E為了便攜性。GNU sed已經接受了-E 作為多年來的無證選項,* BSD seds已經接受 -E 多年以來,但使用的腳本 -E可能不會移植到其他舊系統。擴展正則表達式

-s --separate

默認情況下,sed會將命令行上指定的文件視為單個連續的長流。GNU sed 擴展允許用戶將它們視為單獨的文件:范圍地址(如“/ ABC /,/ DEF /')不允許跨越多個文件,行號相對于每個文件的開始,$指的是每個文件的最后一行,并且從R命令調用的文件在每個文件的開頭都被重繞。

--sandbox

在沙箱模式下, e/w/r命令被拒絕 - 包含它們的程序將被中止而不運行。沙箱模式確保sed 僅在命令行上指定的輸入文件上運行,并且無法運行外部程序。

-u --unbuffered

緩沖輸入和輸出盡可能最低限度。(如果輸入來自“尾巴',您希望盡快看到轉換后的輸出。)

-z --null-data --zero-terminated

將輸入視為一組行,每行以零字節(ASCII'NUL'字符)而不是換行符。此選項可用于命令,如'-z'和'find -print0'來處理任意的文件名。

如果不 -e, -F, - 表達, 要么 - 文件 選項在命令行中給出,則命令行上的第一個非選項參數被視為要執行腳本

如果在處理上述內容后仍有任何命令行參數,這些參數將被解釋為要處理的輸入文件的名稱。 文件名“ - '指標準輸入流。如果沒有指定文件名,將處理標準輸入。



2.3退出狀態

退出狀態為零表示成功,非零值表示失敗。GNU sed返回以下退出狀態錯誤值:

0

成功完成

1

無效的命令,無效的語法,無效的正則表達式或與之一起使用的 GNU sed擴展命令--posix

2

在命令行上指定的一個或多個輸入文件無法打開(例如,如果找不到文件或拒絕讀取權限)。處理繼續與其他文件。

4

I / O錯誤或運行時嚴重的處理錯誤, GNU sed立即中止。

另外,該命令qQ可用于終止 sed與自定義退出代碼值(這是一個GNU sed擴展名):

$ echo | sed'Q42'; echo $? 42 


3個sed腳本


3.1 sed腳本概述

sed程序由一個或多個的sed命令,由一個或多個的傳遞 -e, -F, - 表達,和 - 文件 選項或第一個非選項參數,如果使用這些選項的零。本文將參考“the” sed腳本; 這被理解為意味著傳入的所有腳本腳本文件順序連接。請參閱概述

sed 命令遵循以下語法:

[addr] X [選項] 

X是單字母sed命令。 [addr]是可選的行地址。如果[addr]指定,則命令X將僅在匹配的行上執行。 [addr]可以是單行號,正則表達式或行范圍(請參見sed地址)。額外[options]的用于某些sed命令。

以下示例刪除輸入中的行30到35。 30,35是地址范圍。d是delete命令:

sed '30,35d'input.txt> output.txt 

以下示例打印所有輸入,直到以“FOO'被發現。如果找到這樣的行, sed將以退出狀態42終止。如果沒有找到這樣的行(并且沒有其他錯誤發生),sed 將退出狀態0. /^foo/是一個正則表達式地址。 q是退出命令。42是命令選項。

sed'/ ^ foo / q42'input.txt> output.txt 

一個內的命令腳本腳本文件可以由分號(分離;)或換行符(ASCII 10)。可以指定多個腳本-e 要么 -F 選項。

以下示例都是等效的。他們執行兩個sed 操作:刪除與正則表達式匹配的任何行/^foo/,并替換字符串的所有出現“你好'與'世界“:

sed'/ ^ foo / d; s / hello / world /'input.txt> output.txt   sed -e'/ ^ foo / d'-e's / hello / world /'input.txt> output.txt   echo'/ ^ foo / d'> script.sed  echo's / hello / world /'>> script.sed  sed -f script.sed input.txt> output.txt   echo'/ hello / world /'> script2.sed  sed -e'/ ^ foo / d'-f script2.sed input.txt> output.txt 

命令aci,由于它們的語法,不能被隨后工作作為命令分隔符分號,因此應當用換行被終止或者被放置在的末端腳本腳本文件命令之前也可以帶有可選的非空白字符。請參閱多命令語法



3.2 sed命令摘要

GNU 支持以下命令sed一些是標準的POSIX命令,而另外一些是GNU擴展。每個命令的詳細信息和示例如下。(助記符)顯示在括號中。

a\ text

在一行后附加文本

a text

在一行之后附加文本(替代語法)。

b label

無條件分配標簽標簽可以被省略,在這種情況下,在下一個周期開始。

c\ text

文本替換(更改)行

c text

文本替換(更改)行(替代語法)。

d

刪除圖案空間; 馬上開始下一個循環。

D

如果模式空間包含換行符,則刪除直到第一個換行符的模式空間中的文本,并重新啟動循環與結果模式空間,而不會讀取新的輸入行。

如果模式空間不包含換行符,則會像d執行命令一樣啟動正常的新循環

e

執行在模式空間中找到的命令,并使用輸出替換模式空間; 尾隨的換行被壓制。

e command

執行命令并將其輸出發送到輸出流。該命令可以跨多行運行,除了最后一行之外,還有一個反斜杠。

F

(filename)打印當前輸入文件的文件名(帶尾隨的換行符)。

g

使用保持空間的內容替換圖案空間的內容。

G

在圖案空間的內容中附加換行符,然后將保留空間的內容附加到模式空間的內容。

h

(保持)用圖案空間的內容替換保持空間的內容。

H

在保留空間的內容中附加換行符,然后將模式空間的內容附加到保留空間的內容。

i\ text

在一行之前插入文字

i text

在一行之前插入文本(替代語法)。

l

以明確的形式打印圖案空間。

n

(接下來)如果自動打印未被禁用,請打印圖案空間,然后,無論如何將圖案空間替換為下一行輸入。如果沒有更多的輸入,則sed退出而不處理任何命令。

N

向模式空間添加換行符,然后將下一行輸入追加到模式空間。如果沒有更多的輸入,則sed退出而不處理任何命令。

p

打印圖案空間。

P

打印圖案空間,直到第一個。

q[exit-code]

(退出)退出sed而不處理任何命令或輸入。

Q[exit-code]

(退出)此命令q與圖形空間的內容相同,但不會打印。q一樣,它提供了返回一個退出代碼給調用者的功能。

r filename

讀取文本文件一個文件。例:

R filename

在當前周期結束時或當讀取下一個輸入行時,將一行文件名排隊讀取并插入到輸出流中。

s/regexp/replacement/[flags]

(替換)將正則表達式與模式空間的內容進行匹配。如果找到了,更換匹配的字符串 替換

t label

(測試)分支到標簽,只有當s自上一條輸入行被讀取或條件分支以來已成功 執行時,才能進行標記標簽可以被省略,在這種情況下,在下一個周期開始。

T label

(測試)只有當自上次輸入行被讀取或條件分支以來沒有成功的 ubstitut 分支,才能進行標簽s標簽可以被省略,在這種情況下,在下一個周期開始。

v [version]

(版本)此命令不執行任何操作,但sed如果 不支持GNU sed擴展,或者所請求的版本不可用,則會失敗。

w filename

將模式空間寫入文件名

W filename

將給定的文件名寫入到第一個換行符的模式空間的部分

x

交換保留和模式空格的內容。

y/src/dst/

將與任何源字符匹配的模式空間中的任何字符dest-chars中的相應字符進行音譯

z

(zap)此命令清空模式空間的內容。

#

一個評論,直到下一個換行符。

{ cmd ; cmd ... }

組合幾個命令。

=

打印當前輸入行號(帶有尾隨的換行符)。

: label

指定的位置的標簽為分支命令(b, tT)。


3.3 s命令

s命令(如替代)可能是最重要的sed,有很多不同的選擇。s命令的語法是's / regexp / replacement / flags”。

它的基本概念很簡單:該s命令嘗試將模式空間與提供的正則表達式regexp匹配如果匹配成功,則匹配的模式空間的那部分被替換替換

有關regexp語法的詳細信息,請參閱正則表達式地址

所述替換可以包含?是一個從1到9,包括端點)的引用,這指的是包含在之間的匹配的所述部分?個 及其匹配此外,替換可以包含 引用模式空間的整個匹配部分的未轉義字符。 \n\(\)&

/ 字符可通過任何給定的內的任何其他單個字符被均勻地取代s命令。/ 字符(或任何其他字符代替它使用)可以在出現正則表達式替換 僅當它是由前面\的字符。

最后,作為一個GNU sed擴展,可以包括由一個反斜杠和一個字母的特殊序列 LlUu,或E其含義如下:

\L

將替換為小寫,直到找到\U\E找到,

\l

將下一個字符轉成小寫,

\U

將替換成大寫,直到找到\L\E找到,

\u

將下一個字符轉成大寫字母,

\E

停止案件轉換由\L開始\U

g標志被使用時,情況轉換不會從正常表達式的一個出現傳播到另一個。例如,當執行以下命令時,AB-'在圖案空間:

S / \(B \ \?) -  / X \ U \ 1 /克 

輸出為'axxB”。當更換第一個' - ',''序列只影響'\ 1”。它不影響x更換時被添加到模式空間字符b-xB

在另一方面,\l并且\u做影響了替換文本的其余部分,如果他們之后是一個空的替代。隨著'AB-'在模式空間中,以下命令:

S / \(B \ \?) -  / \ U \ 1X /克 

將取代“ - '與'X'(大寫)和'B-'與'BX”。如果這種行為是不希望的,你可以通過添加一個“。\ E'序后'\ 1' 在這種情況下。

要包括文字\&或在最終替換換行符,一定要早于期望的\&或換行的置換\

s命令可以后跟零個或多個以下標志

g

將替換應用于所有匹配到正則表達式,而不僅僅是第一個。

number

只有更換屆的匹配正則表達式


s指揮 相互作用注意:POSIX標準沒有指定當您混合g數字修飾符時應該發生什么,并且目前在sed實現中沒有廣泛同意的含義對于GNU sed,交互定義為:在數字 th 之前忽略匹配,然后匹配并替換所有匹配的數字

p

如果進行替換,則打印新的圖案空間。

注意:當指定選項pe選項時,兩者的相對排序產生非常不同的結果。一般來說,ep(評估然后打印)是你想要的,但另一方面操作可能對調試是有用的。因此,當前版本的GNU sed特別解釋p了前后選項的存在,e在評估之前和之后 打印模式空間,而一般來說,該s命令的標志只顯示一次。盡管如此,這種行為可能會在將來的版本中發生變化。

w filename

如果進行替換,則將結果寫入命名文件。作為GNU sed擴展,支持兩個特殊的文件名的/ dev /標準錯誤,將結果寫入標準錯誤,以及 的/ dev /標準輸出,寫入標準輸出。3

e

該命令允許從shell命令將輸入管道轉換為模式空間。如果進行替換,則執行在模式空間中找到的命令,并將其空格替換為其輸出。尾隨的換行被壓制; 如果要執行的命令包含NUL字符,則結果未定義這是一個GNU sed擴展。

I i

I正則表達式匹配修飾符是一個GNU 擴展,它使sed匹配正則表達式以不區分大小寫的方式。

M m

M正則表達式匹配修飾符是GNU sed 擴展,它指示GNU sed多行模式下匹配正則表達式修飾符分別引起^$匹配換行符之后的空字符串(除正常行為之外),換行符之前的空字符串。有一些特殊的字符序列(\`\')始終與緩沖區的開頭或結尾相匹配。另外,在多行模式下,句點字符與新行字符不匹配。


3.4常用命令

如果你完全使用sed,你很可能想知道這些命令。

#



#字符開頭的注釋; 評論將持續到下一個換行符。


如果您關心可移植性,請注意,某些實現sed(其不 符合POSIX的)可能僅支持單個單行注釋,然后僅在腳本的第一個字符為a時才支持#


警告:如果sed腳本的前兩個字符#n,那么-n(no-autoprint)選項被強制。如果您想在腳本的第一行發表評論,該評論以字母“?“你不想要這個行為,那么一定要用一個資本”?'或者在'?”。

q [exit-code]

退出sed而不處理任何命令或輸入。

示例:打印第二行后停止:

$ seq 3 | sed 2q  1  2 

此命令只接受一個地址。請注意,如果沒有禁用自動打印,則打印當前圖案空間-n選項。sed腳本返回退出代碼的功能GNU sed擴展。

另請參見GNU sed擴展Q命令,無需打印當前模式空間即可靜默退出。

d

刪除圖案空間; 馬上開始下一個循環。

示例:刪除第二個輸入行:

$ seq 3 | sed 2d  1  3 
p

打印圖案空間(到標準輸出)。此命令通常僅與該命令配合使用-n 命令行選項。

示例:僅打印第二個輸入行:

$ seq 3 | sed -n 2p  2 
n

如果未禁用自動打印,請打印圖案空間,然后,無論如何使用下一行輸入替換圖案空間。如果沒有更多的輸入,則sed退出而不處理任何命令。

該命令對于跳過線是有用的(例如,每第N行處理)。

示例:在每3行執行替換(即兩個n命令跳過兩行):

$ seq 6 | sed'n; n; s /./ x /'  1  2  x  4  5  x 

GNU sed提供的擴展地址語法第一?步驟 ,以實現相同的結果:

$ seq 6 | sed'0?3s /./ x /'  1  2  x  4  5  x 
{ commands }

一組命令可之間被封閉 {}字符。當您希望通過單個地址(或地址范圍)匹配來觸發一組命令時,這特別有用。

示例:執行替換然后打印第二個輸入行:

$ seq 3 | sed -n'2 {s / 2 / X /; p}'  X 

3.5較少使用的命令

雖然可能比上一節更少使用,但是sed可以使用這些命令構建一些非常小的但有用的腳本。

y/source-chars/dest-chars/

將與任何源字符匹配的模式空間中的任何字符dest-chars中的相應字符進行音譯

示例:音譯'AJ'進'0-9“:

$ echo你好世界|  sed'y / abcdefghij / 0123456789 /' 74llo worl3 

/任何給定y命令中字符可以被任何其他單個字符均勻地替換。)

所述的實例/(或者任何其他字符代替它使用), \或換行符可以出現在源極-字符DEST-字符 列表,提供每個實例由逃脫\源極-字符DEST-字符列表必須 包含相同數量的字符(后脫逸出)。

有關tr類似的功能,請參閱GNU coreutils中命令。

a text

追加文本行之后。這是標準命令GNU擴展名a- 有關詳細信息,請參見下文。

示例:添加“你好“第二行之后:

$ seq 3 | SED '2A你好'  1  2  3 

a命令之后的空白空白被忽略。要添加的文本被讀取直到行尾。

a\ text

追加文本行之后。

示例:添加'你好'后第二行( - |表示打印輸出行):

$ seq 3 | sed'2a \  hello'  -  | 1  -  | 2  -  | hello  -  | 3 

a命令將按照此命令(每個但最后一個結尾以及\從輸出中刪除的)命令排隊,以在當前周期結束時或當讀取下一個輸入行時排隊。


作為GNU擴展,此命令接受兩個地址。

處理文本中的轉義序列,因此您應該\\文本中使用打印單個反斜杠。

命令在最后一行之后恢復,而沒有反斜杠(\) - '世界'在下面的例子中:

$ seq 3 | sed'2a \  hello \  world  3s /./ X /'  -  | 1  -  | 2  -  | hello  -  | world  -  | X 

作為GNU擴展,a命令和文本可以分為兩個-e參數,使腳本更容易:

$ seq 3 | sed -e'2a \'-e hello  1  2  hello  3   $ sed -e'2a \'-e“$ VAR” 
i text

在一行之前插入文字這是標準命令GNU擴展名i- 有關詳細信息,請參見下文。

示例:插入“你好“在第二行之前:

$ seq 3 | SED '2I你好'  1  你好 2  3 

i命令之后的空白空白被忽略。要添加的文本被讀取直到行尾。

i\ text

立即輸出跟隨此命令的文本行。

示例:插入'你好'在第二行之前( - |表示打印輸出行):

$ seq 3 | sed'2i \  hello'  -  | 1  -  | hello  -  | 2  -  | 3 

作為GNU擴展,此命令接受兩個地址。

處理文本中的轉義序列,因此您應該\\文本中使用打印單個反斜杠。

命令在最后一行之后恢復,而沒有反斜杠(\) - '世界'在下面的例子中:

$ seq 3 | sed'2i \  hello \  world  s /./ X /'  -  | X  -  | hello  -  | world  -  | X  -  | X 

作為GNU擴展,i命令和文本可以分為兩個-e參數,使腳本更容易:

$ seq 3 | sed -e'2i \'-e hello  1  hello  2  3   $ sed -e'2i \'-e“$ VAR” 
c text

文字代替行這是標準命令GNU擴展名c- 有關詳細信息,請參見下文。

示例:將第2至第9行替換為“你好“:

$ seq 10 | SED '2,9c你好'  1只 10 

c命令之后的空白空白被忽略。要添加的文本被讀取直到行尾。

c\ text

刪除匹配地址或地址范圍的行,并輸出該命令后面的文本行。

示例:用第2至第4行替換“你好'和'世界'( - |表示打印輸出行):

$ seq 5 | sed'2,4c \  hello \  world'  -  | 1  -  | hello  -  | world  -  | 5 

如果沒有給出地址,則替換每一行。

此命令完成后,將啟動一個新的循環,因為模式空間將被刪除。在下面的示例中,c啟動一個新的循環,替換文本不執行替換命令:

$ seq 3 | sed'2c \  hello  s /./ X /'  -  | X  -  | hello  -  | X 

作為GNU擴展,c命令和文本可以分為兩個-e參數,使腳本更容易:

$ seq 3 | sed -e'2c \'-e hello  1  hello  3   $ sed -e'2c \'-e“$ VAR” 
=

打印當前的輸入行號(帶有尾隨的換行符)。

$ printf'%s \ n'aaa bbb ccc | sed =  1  aaa  2  bbb  3  ccc 

作為GNU擴展,此命令接受兩個地址。

l n

以明確的形式打印圖案空間:不可打印的字符(和\字符)以C風格的轉義格式打印; 長行被分割,尾隨\字符表示分割; 每行的末尾都標有a $

n指定所需的換行長度; 長度為0(零)意味著永遠不要纏繞長線。如果省略,則使用在命令行中指定的默認值。所述? 參數是一個GNU sed擴展。

r filename

讀取文本文件一個文件。例:

$ seq 3 | SED '2R的/ etc /主機名稱'  1  2  fencepost.gnu.org  3 

在當前周期結束時或當讀取下一個輸入行時,將要讀取并插入到輸出流中的文件名的內容排隊請注意,如果無法讀取文件名,則將其視為空文件,無任何錯誤指示。

作為GNU sed擴展,特殊值的/ dev /標準輸入 支持文件名,其中讀取標準輸入的內容。


作為GNU擴展,此命令接受兩個地址。然后將文件重新讀取并插入到每個尋址行上。

w filename

將模式空間寫入文件名作為GNU sed擴展,支持兩個特殊的文件名的/ dev /標準錯誤,將結果寫入標準錯誤,以及 的/ dev /標準輸出,寫入標準輸出。4

在讀取第一個輸入行之前,將創建(或截斷)該文件; 引用相同文件名的所有w命令(包括w成功s命令標志的實例)在 不關閉并重新打開文件的情況下輸出。

D

如果模式空間不包含換行符,則會像d執行命令一樣啟動正常的新循環否則,刪除圖形空間中的文本直到第一個換行符,并重新啟動循環與結果模式空間,而不讀取新的輸入行。

N

向模式空間添加換行符,然后將下一行輸入追加到模式空間。如果沒有更多的輸入,則sed退出而不處理任何命令。

什么時候 -z 被使用,零字節(ascii'NUL'字符)添加在行之間(而不是新行)。

sed如果沒有“下一個”輸入行,默認情況下不會終止。這是可以禁用的GNU擴展--posix請參閱最后一行的N命令

P

將圖案空間的部分打印到第一個換行符。

h

使用模式空間的內容替換保持空間的內容。

H

在保留空間的內容中附加換行符,然后將模式空間的內容附加到保留空間的內容。

g

使用保持空間的內容替換圖案空間的內容。

G

在圖案空間的內容中附加換行符,然后將保留空間的內容附加到模式空間的內容。

x

交換保留和模式空格的內容。


3.6 sed大師命令

在大多數情況下,使用這些命令表明,您可能更喜歡像awk Perl 這樣的編程但偶爾有人堅持堅持sed,這些命令可以使一個人寫一個非常復雜的腳本。

: label

[無地址]


指定分支命令標簽位置在所有其他方面,無操作。

b label

無條件分支到標簽標簽可以被省略,在這種情況下,在下一個周期開始。

t label

只有當自上一條輸入行被讀取或有條件分支以來已成功執行ubstitution時,才能進行標記s標簽可以被省略,在這種情況下,在下一個周期開始。


3.7特定于GNU的命令 sed

這些命令是特定于GNU的 sed,所以你必須小心使用它們,只有當你確定阻礙可移植性不是壞的時候。它們允許您檢查GNU sed擴展或者經常需要執行的任務,但不支持標準sed

e [command]

該命令允許從shell命令將輸入管道轉換為模式空間。沒有參數,e命令執行在模式空間中找到的命令,并用輸出替換模式空間; 尾隨的換行被壓制。

如果指定了參數,則該e命令將其解釋為命令,并將其輸出發送到輸出流。該命令可以跨多行運行,除了最后一行之外,還有一個反斜杠。

在這兩種情況下,如果要執行的命令包含NUL字符,則結果是未定義的

請注意,與r命令不同,命令的輸出將立即打印; r命令會將輸出延遲到當前周期的結束。

F

打印當前輸入文件的文件名(帶尾隨的換行符)。

Q [exit-code]

此命令只接受一個地址。


此命令q與圖形空間的內容相同,但不會打印。q一樣,它提供了返回一個退出代碼給調用者的功能。

這個命令可以是有用的,因為完成這個顯而易見的微不足道的功能的唯一替代方法是使用 -n 選項(這可能會使您的腳本不必要地復雜化)或使用以下代碼片段,這樣通過讀取整個文件而浪費時間,而沒有任何明顯的效果:

:吃 $ d 在最后一行靜靜地退出 N 讀另一行,默默地 g 每次覆蓋模式空間以節省內存 b吃 
R filename

在當前周期結束時或當讀取下一個輸入行時,將一行文件名排隊讀取并插入到輸出流中。請注意,如果無法讀取文件名,或者如果文件名達不到,則不附加任何行,沒有任何錯誤指示。

r命令一樣,具有特殊的價值的/ dev /標準輸入 對于從標準輸入讀取一行的文件名是受支持的。

T label

只有在自上次輸入行被讀取或有條件分支以來沒有成功的 ubstitut時,才能進行標記s標簽可以被省略,在這種情況下,在下一個周期開始。

v version

此命令不執行任何操作,但sed如果不支持GNU sed擴展,則會失敗 ,因為其他版本sed不實現。另外,您可以指定sed腳本所需的版本,例如4.0.5默認是4.0 因為這是實現此命令的第一個版本。

此命令即使在環境中設置,可以啟用所有GNU擴展 POSIXLY_CORRECT

W filename

將給定的文件名寫入到第一個換行符的模式空間的部分。w關于文件處理命令下的一切都在這里。

z

此命令清空模式空間的內容。它通常與“小號/.*//',但是效率更高,并且在輸入流中存在無效多字節序列的情況下起作用。 POSIX要求這樣的序列匹配“',所以sed在大多數多字節語言環境(包括UTF-8語言環境)中,沒有可移植的方式清除腳本中間的緩沖區。


3.8多種命令語法

sed 程序中指定多個命令有幾種方法

從文件運行sed腳本時,使用換行符是最自然的(使用 -F 選項)。

在命令行中,所有sed命令可能被換行分隔。或者,您可以將每個命令指定為參數-e 選項:

$ seq 6 | SED '1D  3D  5D'  2  4  6   $ 6序列| sed -e 1d -e 3d -e 5d  2  4  6 

分號(';')可以用來分離最簡單的命令:

$ seq 6 | SED '1D; 3D;圖5d'  2  4  6 

{}btT:命令可以用分號分隔(這是一個非便攜式GNU sed擴展名)。

$ seq 4 | sed'{1d; 3d}'  2  4   $ seq 6 | SED '{1D; 3D};圖5d'  2  4  6 

在使用的標簽btT:指令被讀取,直到一個分號。領先和尾隨的空白被忽略。在下面的例子中,標簽是“X”。第一個例子與GNU一起使用 sed第二個是便攜式的等價物。有關分支和標簽的更多信息,請參閱分支和流控制

$ seq 3 | sed'/ 1 / bx; s / ^ / = /; :X ; 3D”  1  = 2   $ SEQ 3 | SED -e '/ 1 / BX' -e 'S / ^ / = /' -e ':X' -e '3D'  1  = 2 
3.8.1需要換行符的命令

以下命令不能用分號分隔,需要換行符:

aci(追加/變更/插入)

所有字符以下aci命令被作為追加/變更/插入的文本。使用分號會導致不良結果:

$ seq 2 | sed'1aHello; 2D”  1  您好; 2d  2 

使用命令分開 -e 或換行:

$ seq 2 | sed -e 1aHello -e 2d  1  Hello   $ seq 2 | SED '1aHello  2D'  1  你好 

請注意,指定要添加的文本('你好“)后aci本身就是一個GNU sed擴展。符合POSIX標準的便攜式解決方案是:

$ seq 2 | SED '1A \  你好 2D'  1  你好 
# (評論)

所有字符“直到下一個換行符被忽略。

$ seq 3 | sed'#這是一個評論; 2D”  1  2  3   $ SEQ 3 | SED '#這是一條評論 2D'  1  3 
rRwW(讀取和寫入文件)

rRwW命令解析的文件名,直至行尾。如果找到空格,注釋或分號,它們將被包含在文件名中,導致意想不到的結果:

$ seq 2 | sed'1w hello.txt; 2D”  1個 2   $ LS -log  總共4  -rw-RW-R-- 1 23年1月2日23時03 hello.txt的; 2d   $ cat'hello.txt; 2D”  1 

請注意,sed在自動忽略讀/寫錯誤 rRwW命令(如文件丟失)。在以下示例中,sed嘗試讀取名為“hello.txt; ?”。文件丟失,錯誤被忽略:

$ echo x | sed'1rhello.txt; N”  X 
e (命令執行)

e命令之后的任何字符直到行尾都將發送到shell。如果找到空格,注釋或分號,它們將被包含在shell命令中,導致意想不到的結果:

$ echo a | SED '1E觸摸富#酒吧'  一個  $ LS -1  富#酒吧  $回顯| sed'1e touch foo; s / a / b /'  sh:1:s / a / b /:找不到 a 
s///[we](用e代替w

在替換命令中,w標志將替換結果寫入文件,并且該e標志以shell命令執行歸屬結果。r/R/w/W/e命令一樣,這些必須用換行符終止。如果找到空格,注釋或分號,它們將被包含在shell命令或文件名中,從而導致意想不到的結果:

$ echo a | SED的/ A / B / w1.txt#富'  b   $ LS -1  的1.txt#FOO 

4地址:選擇行


4.1地址概述

地址確定sed將執行命令的哪一行以下命令替換“你好'與'世界“只在第144行:

sed'144s / hello / world /'input.txt> output.txt 

如果沒有給出地址,則在所有行上執行命令。以下命令替換“你好'與'世界'在輸入文件的所有行:

sed / s / hello / world /'input.txt> output.txt 

地址可以包含正則表達式,以基于內容而不是行號匹配行。以下命令替換“你好'與'世界“只有在含有”蘋果“:

sed'/ apple / s / hello / world /'input.txt> output.txt 

地址范圍由兩個以逗號(,分隔的地址指定地址可以是數字,正則表達式或兩者的混合。以下命令替換“你好'與'世界“只有4到17行(含):

sed'4,17s / hello / world /'input.txt> output.txt 

!字符附加到地址規范的結尾(在命令字母之前)否定了匹配的感覺。也就是說,如果!字符遵循地址或地址范圍,則僅選擇與地址匹配的以下命令替換“你好'與'世界“只有包含字”蘋果“:

sed'/ apple /!s / hello / world /'input.txt> output.txt 

以下命令替換“你好'與'世界'僅在第1行到第3行和第18行直到輸入文件的最后一行(即排除行4到17):

sed'4,17!s / hello / world /'input.txt> output.txt 

4.2按數字選擇行

sed腳本中的地址可以是以下任何一種形式:

number

指定行號僅與輸入中的行匹配。(請注意,sed除非在所有輸入文件之間連續計數-一世 要么 -s 選項被指定。)

$

該地址與最后一個輸入文件的最后一行匹配,或者每個文件的最后一行 -一世 要么 -s 選項被指定。

first~step

GNU擴展每匹配步驟個開頭的行線第一特別地,當存在非負n使得當前行數等于第一 +(n * 時,將選擇行 因此,1~2可以選擇奇數行和 0~2偶數行; 從第二個開始挑選第三行,2?3“將被使用; 從十號開始選擇第五行,使用'10?5“; 和'50?0“只是一個模糊的說法50

以下命令演示了步驟地址使用情況:

$ seq 10 | SED -N '0?4P'  4  8   $ 10序列| SED -N '1?3P'  1  4  7  10 

4.3通過文本匹配選擇行

GNU sed支持以下正則表達式地址。默認的正則表達式是 基本正則表達式(BRE)如果-E 要么 -r使用選項,正則表達式應為擴展正則表達式(ERE)語法。BRE vs ERE

/regexp/

這將選擇與正則表達式正則表達式匹配的任何行如果regexp本身包含任何/字符,則每個都必須由反斜杠(\轉義

以下命令打印行 / etc / passwd文件 以“慶典5

sed -n'/ bash $ / p'/ etc / passwd 

空的正則表達式“//'重復上一個正則表達式匹配(如果將空的正則表達式傳遞給s命令,則相同)。請注意,正則表達式的修飾符將在編譯正則表達式時進行求值,因此與空正則表達式一起指定它們無效。

\%regexp%

%可以由任何其他單個字符替換。)


這也與正則表達式正則表達式匹配,但允許使用不同的定界符/如果正則表達式本身包含大量斜杠,這是特別有用的,因為它避免了每一個繁瑣的轉義/如果regexp本身包含任何分隔符字符,則每個都必須由反斜杠(\轉義

以下兩個命令是等效的。他們打印以'/家庭/愛麗絲/文件/“:

sed -n'/ ^ \ / home \ / alice \ / documents \ //  p'sed -n'\%^ / home / alice / documents /% p'sed -n'\; ^ / home / alice / documents /; p” 
/regexp/I \%regexp%I

I正則表達式匹配修飾符是GNU 擴展,它使得正則表達式以不區分大小寫的方式匹配。

在許多其他編程語言中,小寫字母i用于不區分大小寫的正則表達式匹配。然而,在sed 該i用于插入命令(TODO:添加pxref)。

觀察以下示例之間的差異。

在這個例子中,/b/I是地址:具有I 修飾符的正則表達式d是delete命令:

$ printf“%s \ n”abc | SED '/ B / ID'  一個 ? 

這里/b/是地址:正則表達式。 i是insert命令。 d是要插入的值。一條線與'?'然后插入匹配的行上方:

$ printf“%s \ n”abc | SED '/ B / ID'  一個 ?  b  ? 
/regexp/M \%regexp%M

M正則表達式匹配修飾符是GNU sed 擴展,它指示GNU sed多行模式下匹配正則表達式修飾符分別引起^$匹配換行符之后的空字符串(除正常行為之外),換行符之前的空字符串。有一些特殊的字符序列(\`\')始終與緩沖區的開頭或結尾相匹配。另外,在多行模式下,句點字符與新行字符不匹配。


4.4范圍地址

可以通過指定兩個以逗號(,分隔的地址來指定地址范圍地址范圍匹配從第一個地址匹配的行開始,直到第二個地址匹配(包括):

$ seq 10 | SED -n '4,6p'  4  5  6 

如果第二個地址是一個正則表達式,然后檢查結束比賽將開始與線以下,其匹配的第一個地址的行:一個范圍將總是跨越至少兩行(當然除了如果輸入流結束時)。

$ seq 10 | SED -n '4 / [0-9] / P'  4  5 

如果第二個地址是一個小于(或等于)匹配所述第一地址的行,那么只有一條線匹配:

$ seq 10 | SED -n '4,1p'  4 

GNU sed還支持一些特殊的雙地址格式; 所有這些都是GNU擴展:

0,/regexp/

0可以在地址規范中使用 行號,以便在第一個輸入行中嘗試匹配正則 表達式換句話說, 類似于,除了如果addr2與輸入的第一行匹配,則 表單將認為其結束范圍,而形式將匹配其范圍的開始,因此使范圍跨度達到第二次出現的正則表達式。 0,/regexp/sed0,/regexp/1,/regexp/0,/regexp/1,/regexp/

請注意,這是唯一0地址有意義的地方; 沒有第0行和命令0 以任何其他方式給出地址將給出錯誤。

以下示例說明從地址1和0開始的區別:

$ seq 10 | SED -n '1,/ [0-9] / P'  1  2   $ SEQ 10 | SED -n '0,/ [0-9] / P'  1 
addr1,+N

匹配ADDR1?以下行ADDR1

$ seq 10 | SED -N '6,+ 2P'  6  7  8 

addr1可以是行號或正則表達式。

addr1,~N

匹配addr1addr1 之后的行,直到輸入行號為N的倍數的下一行以下命令從第6行開始,直到下一行為4的倍數(即第8行):

$ seq 10 | SED -n '6,?4P'  6  7  8 

addr1可以是行號或正則表達式。


5正則表達式:選擇文本


5.1正則表達式概述 sed

要知道如何使用sed,人們應該了解的正則表達式(正則表達式的簡稱)。正則表達式是從左到右匹配主題字符串的模式。大多數字符是 普通的:它們代表自己的模式,并且匹配相應的字符。正則表達式在sed兩個斜杠之間指定。

以下命令打印包含單詞“你好“:

sed -n'/ hello / p' 

上面的例子相當于這個grep命令:

grep'你好 

正則表達式的力量來自于在模式中包含替代和重復的能力。這些是通過使用特殊字符在模式中編碼的,這些字符不代表自己,而是以某種特殊方式進行解釋。

^正則表達式中的字符(插入符號)與行的開頭匹配。字符.(點)匹配任何單個字符。以下sed命令匹配并打印以字母“b',其次是任何一個字符,其次是字母'?“:

$ printf“%s \ n”abode bad bed bit bid byte body | sed -n'/ ^ bd / p'  招標 機構 

以下部分說明正則表達式中特殊字符的含義和用法。


5.2基本(BRE)和擴展(ERE)正則表達式

基本和擴展正則表達式是指定模式語法的兩個變體。基本正則表達式(BRE)是sed(和類似的)中的默認值grep擴展正則表達式語法(ERE)被激活-r 要么 -E選項(和類似地,grep -E)。

GNU中 sed,基本和擴展正則表達式的唯一區別在于幾個特殊字符的行為:'''+',括號,大括號('{}'),和'|”。

使用基本(BRE)語法,這些字符沒有特殊的含義,除非前綴反斜杠('\“); 雖然使用擴展(ERE)語法是相反的:這些字符是特殊的,除非它們帶有反斜杠('\“)。

所需模式 基本(BRE)語法 擴展(ERE)語法
文字'+'(加號)
$ echo“a + b = c”| sed -n'/ a + b / p'a  + b = c 
$ echo“a + b = c”| sed -E -n'/ a \ + b / p'a  + b = c 
一個或多個 '一個'字符后跟'b'(加號作為特殊元字符)
$ echo“aab”| sed -n'/ a \ + b /  p'aab 
$ echo“aab”| sed -E -n'/ a + b /  p'aab 

5.3基本正則表達式語法概述

以下是正則表達式語法的簡要說明sed

char

一個普通字符與自己相匹配。

*

匹配上一個正則表達式的零個或多個匹配實例的序列,該正則表達式必須是普通字符,前綴為\.,分組的正則表達式(見下文)或括號表達式的特殊字符作為GNU擴展,后綴正則表達式也可以后跟*例如,a**相當于a*。 POSIX 1003.1-2001表示,*當它出現在正則表達式或子表達式的開始時,它代表自身,但是許多非GNU實現不支持這一點,便攜式腳本應該\*在這些上下文中使用

.

匹配任何字符,包括換行符。

^

匹配模式空間開始處的空字符串,即,在模式空格開始之后,必須顯示出來的內容。

在大多數腳本中,模式空間被初始化為每行的內容(請參閱如何sed工作)。所以,這是一個有用的簡化,認為是^#include只匹配線,#包括'是線上的第一件事 - 如果以前有空格,比如匹配失敗。只要模式空間的原始內容不被修改,例如使用s命令,這種簡化是有效的

^僅在正則表達式或子表達式(即,之后\(或 之后\|的開始處作為特殊字符^盡管如此,便攜式腳本在子表達式開始時應避免,因為POSIX允許^在該上下文中將其視為普通字符。

$

它是一樣的^,而是指模式空間的結尾。 $也只能在正則表達式或子表達式(即,之前\) 或之前\|的結尾處作為特殊字符,并且在子表達式結尾處的使用不可移植。

[list] [^list]

匹配列表中的任何單個字符:例如, [aeiou]匹配所有元音。列表可以包括與(包括)char1 和char2之間的任何字符匹配的序列請參閱字符類和括號表達式char1-char2

\+

因為*,但匹配一個或多個。這是一個GNU擴展。

\?

作為*,但只匹配零或一。這是一個GNU擴展。

\{i\}

As *,但是恰好匹配i序列(是一個十進制整數;為了便攜性,保持在0到255之間)。

\{i,j\}

匹配ij,包括序列。

\{i,\}

匹配大于或等于i序列。

\(regexp\)

將內部正則表達式組合為一個整體,這用于:

  • 應用postfix操作符,如\(abcd\)*:這將搜索零個或多個整個序列'A B C D',同時abcd*會搜索'ABC“其次是零次或多次出現”?”。請注意,POSIX 1003.1-2001 \(abcd\)*需要支持,但許多非GNU 實現不支持它,因此它不是普遍可移植的。
  • 使用回參考(見下文)。
regexp1\|regexp2

匹配regexp1regexp2使用括號來使用復雜的替代正則表達式。匹配過程從左到右依次嘗試每個替代,并且使用成功的第一個。這是一個GNU擴展。

regexp1regexp2

匹配regexp1regexp2的連接級聯地結合不同于更緊密\|^和 $,但較不緊密比其他正則表達式運算符。

\digit

匹配的數字\(…\)正則表達式括號子表達式。這被稱為反參考子表達式通過計數\(從左到右的出現來隱含地編號

\n

匹配換行符。

\char

匹配,其中,焦炭是一個$, *.[\,或^請注意,您可以移植地假定要解釋的只有C樣的反斜杠序列是\n\\特別 \t是不便攜,并且匹配'?“在大多數實現的sed,而不是制表符字符。

請注意,正則表達式匹配器是貪心的,即從左到右嘗試匹配,如果從同一個字符開始可以進行兩次或多次匹配,則選擇最長的匹配項。

例子:

ABCDEF

火柴 'ABCDEF”。

A * B

匹配零個或多個'一個之后是一個單一的“b”。例如, 'b' 要么 'AAAAAB”。

一\ 2 B

火柴 'b' 要么 'AB”。

一個\ + B \ +

匹配一個或多個'一個其次是一個或多個'b的:'AB“是最短的匹配,但其他例子是”AAAAB' 要么 'abbbbb' 要么 'aaaaaabbbbbbb”。

*。 。\ +

這兩個都匹配字符串中的所有字符; 但是,第一個匹配每個字符串(包括空字符串),而第二個匹配只包含至少一個字符的字符串。

^為主。*(。*)

這匹配一個以'主要',其次是開口和右括號。?''''和'“不必相鄰。

^#

這匹配一個以'”。

\\ $

這將匹配以單個反斜杠結尾的字符串。正則表達式包含兩個用于轉義的反斜杠。

\ $

而是匹配一個由一個美元符號組成的字符串,因為它被轉義。

[A-ZA-Z0-9]

在C語言環境中,它匹配任何ASCII字母或數字。

[^ tab] \ +

(這里tab表示單個制表符。)這匹配一個或多個字符的字符串,其中沒有一個是空格或制表符。通常這意味著一個字。

^ \(。* \)\ n \ $ 1

這將匹配由由換行符分隔的兩個相等子串組成的字符串。

\ {9 \}一個$

這匹配九個字符,后跟一個'一個“在一行的結尾。

^ \ {15 \}甲

這匹配一個包含16個字符的字符串的開頭,最后一個是'一個”。


5.4擴展正則表達式語法概述

基本和擴展正則表達式的唯一區別在于幾個字符的行為:'''+',括號,大括號('{}'),和'|”。雖然基本的正則表達式要求將它們轉義為特殊字符,但如果您希望它們與文字字符匹配,則使用擴展正則表達式時,必須將其轉義|因為'\ |'是一個GNU擴展 - 標準的基本正則表達式不提供其功能。

例子:

abc?

成為'ABC \?'使用擴展正則表達式時。它匹配文字字符串'ABC?”。

c\+

成為'C +'使用擴展正則表達式時。它匹配一個或多個'C的。

a\{3,\}

成為'一個{3,}'使用擴展正則表達式時。它匹配三個或更多的'一個的。

\(abc\)\{2,3\}

成為'(ABC){2,3}'使用擴展正則表達式時。它匹配“ABCABC' 要么 'ABCABCABCABC ...”。

\(abc*\)\1

成為'(ABC *)\ 1'使用擴展正則表達式時。使用擴展正則表達式時,還需要轉義引用引用。

a\|b

成為'A | B'使用擴展正則表達式時。它匹配'一個' 要么 'b”。


5.5字符類和括號表達式

括號表達式是由包圍字符的列表'['和']”。它匹配該列表中的任何單個字符; 如果列表的第一個字符是插入符號'^',那么它匹配任何不在列表中的字符例如,以下命令將替換“灰色' 要么 '灰色'與'藍色“:

sed的/ gr [ae] y / blue /' 

括號表達式可用于 基本擴展 正則表達式(即,帶或不帶-E/-r 選項)。

在括號表達式中,范圍表達式由用連字符分隔的兩個字符組成。它匹配在兩個字符之間排序的任何單個字符(包括)。在默認的C語言環境中,排序順序是本地字符順序; 例如, '[廣告]'相當于'[A B C D]”。

最后,某些命名類的字符是在括號表達式中預定義的,如下所示。

這些命名類必須括號內使用正確使用:

$ echo 1 | sed's / [[:digit:]] / X /'  X 

不正確的使用被較新的sed版本拒絕舊版本接受它,但將其視為單括號表達式(相當于“[DGIT:]',也就是只有字符d / g / i / t /:)

#當前的GNU sed版本 - 不正確的使用被拒絕 $ echo 1 | sed的/ [:digit:] / X /'  sed:字符類的語法是[[:space:]],而不是[:space:]   #舊的GNU sed版本 $ echo 1 | sed / s / [:digit:] / X /'  1 
[:alnum:]

字母數字字符: '[:α:]'和'[:數字:]“; 在里面 'C'區域設置和ASCII字符編碼,這與'[0-9A-ZA-Z]”。

[:α:]

字母字符:'[:降低:]'和'[:上:]“; 在里面 'C'區域設置和ASCII字符編碼,這與'[A-ZA-Z]”。

[:空白:]

空白字符:空格和制表符。

[:CNTRL:]

控制字符 在ASCII中,這些字符具有八進制代碼000到037和177(DEL)。在其他字符集中,這些是相同的字符,如果有的話。

[:數字:]

數字:0 1 2 3 4 5 6 7 8 9

[:圖形:]

圖形字符:'[:alnum:]'和'[:PUNCT:]”。

[:降低:]

小寫字母; 在里面 'C'區域設置和ASCII字符編碼,這是 a b c d e f g h i j k l m n o p q r s t u v w x y z

[:打印:]

可打印字符:'[:alnum:]'''[:PUNCT:]'和空間。

[:PUNCT:]

標點符號 在里面 'C'區域設置和ASCII字符編碼,這是 ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~

[:空間:]

空間人物:在'C'locale,這是標簽,換行符,垂直標簽,表單feed,回車和空格。

[:上:]

大寫字母:在'C'區域設置和ASCII字符編碼,這是 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

[:xdigit:]

十六進制數字: 0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f

請注意,這些類名稱中的括號是符號名稱的一部分,除了括號表達式的括號之外,還必須包含它們。

大多數元字符在括號表達式中喪失其特殊含義:

]

如果不是第一個列表項,則結束括號表達式。所以,如果你想讓']'字符是一個列表項,你必須把它放在第一位。

 - 

表示范圍,如果它不是列表中的第一個或最后一個或范圍的終點。

^

表示不在列表中的字符。如果你想讓'^'字符列表項,放在任何地方,但首先。

TODO:并入本段(從BRE部分逐字復制)。

字符$*.[,和\ 通常不中的特殊列表例如,[\*] 匹配“\' 要么 '*'因為\這里不是特別的。然而,字符串等[.ch.][=a=]和 [:space:]是內特殊列表和表示對照的符號,等價類,和字符類,分別和 [因此特別內列表時,它后面是 .=,或:此外,在不 POSIXLY_CORRECT模式,特殊的逃逸喜歡\n和 \t內確認名單看到逃生

[

表示開放的整理符號。

]

代表緊密整理符號。

[=

表示開放等價類。

=]

代表密切的等價類。

[:

表示打開的字符類符號,后面應該有一個有效的字符類名稱。

:]

代表關閉字符類符號。


5.6正則表達式擴展

以下序列在正則表達式中具有特殊含義(在地址s命令中使用)。

這些可以用于 基本擴展 正則表達式(即,使用或不使用-E/-r 選項)。

\w

匹配任何“單詞”字符。“字”字符是任何字母或數字或下劃線字符。

$ echo“abc% -  = def”。| sed / / w / X /  g'XXX% -  = XXX。 
\W

匹配任何“非字”字符。

$ echo“abc% -  = def”。| sed的/ \ W / X /  g'abcXXXXXdefX 
\b

匹配單詞邊界; 如果左邊的字符是“字”字符,并且右邊的字符是“非字”字符,則反之亦然。

$ echo“abc% -  = def”。| sed的/ \ b / X /  g'XabcX% -  = XdefX。 
\B

匹配到處都是字邊界; 如果左邊的字符和右邊的字符既是“字”字符也可以是“非字”兩個字符,那就是匹配。

$ echo“abc% -  = def”。| sed的/ \ w / X /  g'aXbXc X%XX = X dXeXf.X 
\s

匹配空格字符(空格和制表符)。嵌入模式/保持空格的換行符也將匹配:

$ echo“abc% -  = def”。| sed / s / X /  g'abcX% -  = Xdef。 
\S

匹配非空格字符。

$ echo“abc% -  = def”。| sed的/ \ w / X /  g'XXX XXX XXXX 
\<

匹配一個單詞的開頭。

$ echo“abc% -  = def”。| sed's / \ <!-- X /  g'Xabc% -  = Xdef。 
\>

匹配一個單詞的結尾。

$ echo“abc% -  = def”。| sed's / \> / X /  g'abcX% -  = defX。 
\`

只匹配模式空間的開始。這與^多行模式不同。

比較以下兩個例子:

$ printf“a \ nb \ nc \ n”| sed'N; N; s / ^ / X /  gm'Xa  Xb  Xc   $ printf“a \ nb \ nc \ n” sed'N; N; s / \`/ X /  gm'Xa  b  c 
\'

僅匹配模式空間的結尾。這與$多行模式不同。


5.7反向引用和子表達式

反向引用是指匹配的正則表達式的前一部分的正則表達式命令。反向引用使用反斜杠和單個數字(例如“\ 1“)。它們引用的正則表達式的一部分稱為 子表達式,并用括號指定。

反向引用和子表達式用于兩種情況:正則表達式搜索模式和命令替換部分s(請參閱正則表達式地址“s”命令)。

在正則表達式模式中,使用反向引用來匹配與先前匹配的子表達式相同的內容。在下面的例子中,子表達式是'' - 任何單個字符(被括號括起來使其成為子表達式)。反參考“\ 1'要求與子表達式匹配相同的內容(相同字符)。

下面的命令匹配以任何字符開始的單詞,后跟字母“?',其次是與第一個相同的字符。

$ sed -E -n'/^(.)o\1$/p'/ usr / share / dict / words  bob  mom  non  pop  sos  tot  wow 

多個子表達式將從左到右自動編號。此命令搜索6個字母的回文(前三個字母為3個子表達式,后跟3個反向引用相反順序):

$ sed -E -n'/^(.)(.)(.)\3\2\1$/p'/ usr / share / dict / words  redder 

s命令中,可以在替換部分中使用反向引用來引用regexp部分中的表達式

以下示例使用正則表達式中的兩個子表達式來匹配兩個空格分隔的單詞。替換部件中的反向引用以不同的順序打印單詞:

$ echo“James Bond”| sed -E /(.*)(。*)/名稱為\ 2,\ 1 \ 2. /'  名稱為Bond,James Bond。 

當與交替使用時,如果組不參與匹配,則反向引用使整個匹配失敗。例如, '一個(。)| b \ 1“不匹配”BA”。當給出多個正則表達式時-e 或從文件('-f 文件'),反向引用是每個表達式的本地。


5.8轉義序列 - 指定特殊字符

直到本章,我們才遇到過“\ ^“,它sed不會把回旋解釋為一個特殊的角色,而是從字面上來說。例如, '\ *'匹配單個星號,而不是零個或多個反斜杠。

本章介紹了另外一種逃逸6,即應用于字符或字符序列的轉義,這些字符或序列通常是字面上的,并sed以特殊字符替代。這提供了以可見方式對圖案中的不可打印字符進行編碼的方法。sed腳本中的非打印字符的外觀沒有限制,但是當在shell中編寫腳本或通過文本編輯時,通常使用以下轉義序列之一比其代表的二進制字符更容易:

這些轉義的列表是:

\a

產生或匹配BEL字符,即“警報”(ASCII 7)。

\f

生成或匹配換頁(ASCII 12)。

\n

生成或匹配換行符(ASCII 10)。

\r

生成或匹配回車符(ASCII 13)。

\t

生成或匹配水平選項卡(ASCII 9)。

\v

產生或匹配所謂的“垂直標簽”(ASCII 11)。

\cx

產生或匹配,其中x是任何字符。CONTROL-x\ c x'如下:如果x是小寫字母,則將其轉換為大寫字母。然后字符(十六進制40)的第6位被反轉。因此'\ CZ'變成十六進制1A,但'\C{'變成十六進制3B,而'\C;'變成十六進制7B。

\dxxx

生成或匹配十進制ASCII值為xxx的字符

\oxxx

生成或匹配八進制ASCII值為xxx的字符

\xxx

生成或匹配十六進制ASCII值為xx的字符

\ b由于與現有的“字邊界”的沖突,“(退格)被忽略。


5.9語言環境注意事項

TODO:修復以下段落(從“括號表達式”部分逐字復制)。

TODO:提到語言環境支持在很大程度上取決于OS / libc,而不是sed。

當前區域設置會影響與sed正則表達式匹配的字符

在其他地區,排序順序沒有指定,而'[廣告]“可能相當于”[A B C D]' 或者 '[aBbCcDd]',或者它可能無法匹配任何字符,或者它匹配的字符集可能甚至是不規則的。要獲得對括號表達式的傳統解釋,可以使用“C'locale通過將 LC_ALL環境變量設置為值'C”。

#TODO:是否有任何真實世界的系統/區域設置'A'  #被' - '替換? $ echo A | SED的/ [AZ] / - /'  

他們的解釋取決于LC_CTYPE地區; 例如, '[[:alnum:]]是指當前語言環境中的數字和字母的字符類。

TODO:整理的示例

#TODO:這適用于glibc系統,而不是在musl-libc / freebsd / macosx上。 $ printf'clich?©\ n'| LC_ALL = fr_FR.utf8 sed's / [[= e =]] / X /  g'clichX 

6高級sed:循環和緩沖區


下一個:保持和模式緩沖區,向上:高級sed   [ 目錄 ] [ 索引 ]

6.1 sed工作原理

sed維護兩個數據緩沖區:活動模式空間和輔助保持空間。兩者最初都是空的。

sed通過在每行輸入上執行以下循環來操作:首先,sed從輸入流中讀取一行,刪除任何尾隨的換行符,并將其放在模式空間中。然后執行命令; 每個命令可以具有與之相關聯的地址:地址是一種條件代碼,只有在執行命令之前驗證條件時才執行命令。

當腳本結束到達時,除非 -n選項正在使用中,模式空間的內容將打印到輸出流中,如果刪除尾隨的換行符,則返回。7然后下一個循環開始下一個輸入行。

除非特殊命令(如“?'),在兩個周期之間刪除模式空間。另一方面,保持空間將數據保留在周期之間(參見命令'H'''H'''X'''G'''G'在兩個緩沖區之間移動數據)。


6.2保持和模式緩沖區

去做



6.3多線技術 - 使用D,G,H,N,P來處理多條線

多行可以如一個緩沖器使用被處理 DGHNP它們類似于其小寫同行(dg, hnp),所不同的是這些命令追加或同時尊重嵌入換行符減去數據-允許從圖案添加和刪除行和保持的空間。

它們的操作如下:

D

從模式空間中刪除行直到第一個換行符,然后重新啟動循環。

G

行從保留空間追加到模式空間,并在其前加上換行符。

H

線從模式空間追加到保持空間,并在其前面加上換行符。

N

行從輸入文件追加到模式空間。

P

從圖案空間打印到第一個換行符。

以下示例說明了操作N和 D命令:

$ seq 6 | sed -n'N; l; D'  1 \ n2 $  2 \ n3 $  3 \ n4 $  4 \ n5 $  5 \ n6 $ 
  1. sed 首先將第一行讀入模式空間(即'1“)。
  2. 在每個循環開始時,N 命令將附加一個換行符和下一行到模式空間(即'1'''\ n'''2'在第一個周期)。
  3. l命令明確地打印模式空間的內容。
  4. D然后,命令將圖形空間的內容移除到第一個換行符(離開'2“在第一個周期結束時)。
  5. 在下一個循環中,N命令將一個換行符和下一個輸入行添加到模式空間(例如“2'''\ n'''3“)。

處理文本塊(例如段落(而不是逐行))的常用技術是使用以下構造:

sed'/./{H;$!d}; X ; S / REGEXP / REPLACEMENT /” 
  1. 第一個表達式/./{H;$!d}在所有非空行上運行,并將當前行(在模式空間中)添加到保留空間。在除最后一行之外的所有行上,模式空間被刪除,周期重新啟動。
  2. 的其他表達式xs僅在空行(即,段分隔符)來執行。x命令將累積的行從保留空間中取回到模式空間。s///然后,該 命令對段落中的所有文本(包括嵌入的換行符)進行操作。

以下示例演示了此技術:

$ cat input.txt  aaa aa aaa  aaaa aaaa aa  aaaa aaa aaa   bbbb bbb bbb  bb bb bbb bb  bbbbbbbb bbb   ccc ccc cccc  cccc ccccc c  cc cc cc cc   $ sed'/./{H;$!d}; X ; s / ^ / \ nSTART  - > /; s / $ / \ n < -  END /'input.txt   START  - >  aaa aa aaa  aaaa aaaa aa  aaaa aaa aaa  < -  END   START  - >  bbbb bbb bbb  bb bb bbb bb  bbbbbbbb bbb  < -  END   START - >  ccc ccc cccc  cccc ccccc c  cc cc cc cc  < -  END 

有關更多注釋的示例,請參閱跨多行的文本搜索 和行長度調整


6.4分支和流量控制

分支命令bt并且T能夠改變sed程序的流程

默認情況下,sed將輸入行讀入模式緩沖區,然后繼續按順序處理所有命令。沒有地址的命令影響所有行。具有地址的命令僅影響匹配行。請參閱執行循環地址概述

sed不支持典型的if/then結構。相反,一些命令可以用作條件或更改默認流控制:

d

刪除(清除)當前的圖案空間,并重新啟動程序循環,而不處理其余的命令,而不打印圖案空間。

D

刪除圖形空間的內容直到第一個換行符,并重新啟動程序循環,而不處理其余的命令,而不打印圖案空間。

[addr]X [addr]{ X ; X ; X } /regexp/X /regexp/{ X ; X ; X }

地址和正則表達式可以用作if/then 條件:如果[addr]與當前模式空間匹配,請執行命令。例如:該命令/^#/d表示: 如果當前模式與正則表達式^#(以哈希開始的行)匹配執行d命令:刪除該行而不打印該行,并立即重新啟動程序循環。

b

無條件分支(即:總是跳到標簽,跳過或重復其他命令,而不重新啟動新的循環)。結合地址,可以在匹配的行上有條件地執行分支。

t

分支條件(即:跳轉到一個標簽)只有一個 s///命令已成功自上次輸入行讀取或其他條件分支被采用。

T

類似但與t命令相反:只有在從最后一條輸入行被讀取以來沒有成功的替換時才會分支

以下兩個sed程序是等效的。第一個(設計的)示例使用b命令來跳過s/// 包含'1”。第二個例子使用一個帶有否定的地址('')僅在所需的行上執行替換。y///命令仍然執行在所有行:

$ printf'%s \ n'a1 a2 a3 | sed -E'/ 1 / bx; s / a / z /; :X ; y /  123/456 /'  a4 z5  z6   $ printf'%s \ n'a1 a2 a3 | sed -E'/ 1 /!s / a / z /; y /  123/456 /'  a4 z5  z6 
6.4.1分支和周期

bt并且T命令可被隨后的標簽(通常是一個字母)。標簽用冒號定義,后跟一個或多個字母(例如“:X“)。如果省略標簽,則分支命令重新啟動循環。注意分支到標簽和重新啟動循環之間的區別:重新啟動循環時,sed首先打印模式空間的當前內容,然后將下一個輸入行讀入模式空間; 跳到標簽(即使在程序開頭)也不會打印圖案空間,也不會讀取下一個輸入行。

以下程序是無操作的。b命令(在程序中僅命令)不具有一個標簽,并由此簡單地重新開始該循環。在每個循環中,打印圖案空間,并讀取下一個輸入行:

$ seq 3 | sed b  1  2  3 

以下示例是無限循環 - 它不會終止,也不會打印任何內容。b命令跳轉到“X'標簽,一個新的循環從未開始:

$ seq 3 | sed':x; bx'   #上述命令需要gnu sed(支持附加 #命令后面的標簽,不帶換行符)。一個便攜式的等價物: #sed -e':x'-e bx 

分支通常用nN命令來補充:兩個命令都將下一個輸入行讀入模式空間,而無需等待重新啟動循環。在讀取下一個輸入行之前,n 打印當前圖案空間,然后將其排空,同時N將一個換行符和下一個輸入行附加到模式空間。

考慮以下兩個例子:

$ seq 3 | sed':x; n; BX”  1  2  3   $ SEQ 3 | sed':x; N; BX”  1  2  3 
  • 盡管沒有開始新的循環,這兩個例子都不會進行循環。
  • 在第一個示例中,n命令首先打印模式空間的內容,清空模式空間,然后讀取下一個輸入行。
  • 在第二個示例中,N命令將下一個輸入行附加到模式空間(帶換行符)。線路在圖形空間中累積,直到沒有更多輸入行讀取,則N命令終止sed程序。當程序終止時,執行周期結束動作,并打印整個模式空間。
  • 第二個例子需要GNU sed,因為它使用非POSIX標準的行為N請參閱報告錯誤中的N “最后一行的命令”一節
  • 要進一步檢查兩個示例之間的區別,請嘗試以下命令:
    printf'%s \ n'aa bb cc dd | sed':x; n; =; bx'printf'  %s \ n'aa bb cc dd | sed':x; N; =; bx'printf'  %s \ n'aa bb cc dd | sed':x; n; s / \ n / *** /; bx'printf'  %s \ n'aa bb cc dd | sed':x; N; s / \ n / *** /; BX” 
6.4.2分支示例:連線

作為使用分支的現實世界示例,請考慮通常用于對電子郵件進行編碼引用可打印文件的情況 在這些文件中,長行被分割并標有一個軟線路斷點, 由一個單一的“='字符在行尾:

$ cat jaques.txt  所有的wor =  ld都是stag =  e, 而所有=  男人和 男人只是男人=  玩家: 他們有t =  繼承人退出=  和他們的e =  ntrances;  一個人=  在他的tim =  e扮演man =  y部分。 

以下程序使用地址匹配'/ = $ /'作為條件:如果當前模式空間以'=',它讀取下一個輸入行使用N,替換所有'='字符,其后面是換行符,并且無條件地將branch(b)分配到程序的開頭,而不重新啟動新的循環。如果圖案空間不以“=',執行默認動作:打印模式空間并啟動新的循環:

$ sed':x; / = $ / {N; s / = \ n // g; bx}'jaques.txt  所有的世界都是一個舞臺, 所有的男人和女人只是一個玩家: 他們有出口和入口;  一個人在他的時間玩很多部分。 

這是一個替代程序,略有不同的方法:除了最后一行之外的所有行,N將行添加到模式空間。替換命令然后刪除軟換行符('=“在一行的末尾,即后跟一個換行符),用空字符串替換它們。 如果替換成功(意味著模式空間包含應該連接的行),條件轉移命令將t跳轉到程序的開頭,而不必完成或重新啟動循環。如果替換失敗(意味著沒有換行符),則該t命令不會分支。然后,P將打印圖案空間內容直到第一個換行,D 并將刪除圖案空間內容直到第一個新行。(如需了解更多有關NPD命令看多線技術)。

$ sed':x; $!N; s / = \ n //; tx; P; D'jaques.txt  所有的世界都是一個舞臺, 所有的男人和女人只是玩家: 他們有他們的出口和入口;  一個人在他的時間玩很多部分。 

有關更多線連接示例,請參閱連接線


7一些示例腳本

這里有一些sed腳本可以指導您掌握掌握的技巧 sed


下一步:定心線,向上:示例   [ 內容 ] [ 索引 ]

7.1連線

本節使用NDP命令以處理多行,并且bt分支命令。請參閱多線技術分支和流控制

加入特定行(例如,如果第2和第3行需要連接):

$貓lines.txt  你好 HEL  LO  你好  $ sed的'2 {N; S / \ n //;}' lines.txt  你好 你好 你好 

加入反斜杠 - 繼續行:

$ cat 1.txt  這個\  is \  a \  long \  line  和另一個\  line   $ sed -e':x / \\ $ / {N; s / \\\ n // g; bx}'1.txt  這是一條長行 ,另一行  #TODO:上面需要gnu sed。 #non-gnu seds需要在':'和'b'之后換行 

加入以空格開頭的行(例如SMTP標頭):

$ cat 2.txt  主題:Hello  World  Content-Type:multipart / alternative;  boundary = 94eb2c190cc6370f06054535da6a  日期:星期二,2017年1月3日19:41:16 +0000(GMT) 驗證結果:mx.gnu.org;  dkim = pass header.i=@gnu.org;  spf = pass  Message-ID:  來自:John Doe   To:Jane Smith    $ sed -E':a; $!N; s / \ n \ s + / /; ta P; D'2.txt  主題:Hello World  Content-Type:multipart / alternative; boundary = 94eb2c190cc6370f06054535da6a  日期:星期二,2017年1月3日19:41:16 +0000(GMT) 驗證結果:mx.gnu.org; dkim = pass header.i=@gnu.org; SPF =通 Message-ID:  來自:John Doe   To:Jane Smith    #一個便攜式(非gnu)變體:#sed  -e:a  - e'$!N; s / \ n * / /; ta'-e'P; D' 

7.2中心線

這個腳本將文件的所有行都放在80列的寬度上。要更改該寬度,\{…\}必須更換數字,并且必須更改添加空格的數量。

請注意緩沖區命令如何用于分離正則表達式中要匹配的部分 - 這是一種常見的技術。

#!/ usr / bin / sed -f 
#在緩沖區中放置80個空格 1 {  x  s / ^ $ / /  s /^.*$/&&&&&&&&/  x  } 

#刪除前導和尾隨空格 y / tab/ /  s / ^ * //  s / * $ // 

#添加一個換行符和80個空格到行結束 G 

#保持前81個字符(80 +一個換行符) s / ^ \(。\ {81 \} \)。* $ / \ 1 / 

#\ 2匹配一半的空格,這些空格被移動到開頭 s / ^ \(。* \)\ n \(。* \)\ 2 / \ 2 \ 1 / 

7.3增加數字

這個腳本是演示如何進行算術的幾個腳本之一sed這的確是可能的,8但必須手動完成。

要增加一個數字,只需將1加到最后一位數字,將其替換為以下數字。有一個例外:當數字是九位數時,前面的數字也必須遞增,直到沒有九位數字。

Bruno Haible的這個解決方案非常聰明聰明,因為它使用單個緩沖區; 如果您沒有此限制,則編號行中使用的算法更快。它通過用下劃線替換尾隨九進制,然后使用多個s命令遞增最后一個數字,然后再次用0來替換下劃線。

#!/ usr / bin / sed -f   / [^ 0-9] / d 
#替換所有尾隨的9s by _(除數字之外的任何其他字符,可以使用 #) :d  s / 9 \(_ * \)$ / _ \ 1 /  td 

#incr只有最后一位數字。 如果我們必須添加一個數字,第一行添加最重要的#位數1。 

S / ^ \(_ * \)$ / 1 \ 1 /; tn  s / 8 \(_ * \)$ / 9 \ 1 /; tn  s / 7 \(_ * \)$ / 8 \ 1 /; tn  s / 6 \(_ * \)$ / 7 \ 1 /; tn  s / 5 \(_ * \)$ / 6 \ 1 /; tn  s / 4 \(_ * \)$ / 5 \ 1 /; tn  s / 3 \(_ * \)$ / 4 \ 1 /; tn  s / 2 \(_ * \)$ / 3 \ 1 /; tn  s / 1 \(_ * \)$ / 2 \ 1 /; tn  s / 0 \(_ * \)$ / 1 \ 1 /; TN 

:n  y / _ / 0 / 

7.4將文件重命名為小寫

這是一個非常奇怪的用法sed我們轉換文本,并將其轉換為shell命令,然后將其提供給shell。不要擔心,使用時更糟糕的是黑客sed我看到一個腳本將輸出date轉換為bc程序!

其主體是sed腳本,將名稱從下到上(或反之亦然)重新映射,甚至檢查重映射的名稱是否與原始名稱相同。注意腳本如何使用shell變量和正確的引用進行參數化。

#!/ bin / sh  #rename files to lower / upper case ...  ## usage: #move-to-lower *  #move-to-upper *  #或 #move-to-lower -R。 #move-to-upper -R。 

help() {  cat << eof  用法:$ 0 [-n] [-r] [-h]文件... 

- 不做任何事情,只看到會做什么 -R遞歸(使用find) -h這個消息 文件文件重映射到小寫 

示例: $ 0 -n *(看是否一切正常,然后...) $ 0 * 
 $ 0 -R。 
eof  } 

apply_cmd ='sh'finder ='  echo“$ @”| tr“”“\ n”'  files_only = 

while: do-  case“$ 1”in  -n)apply_cmd ='cat';;  -R)finder ='find“$ @”-type f';;  -h)幫助; 出口1 ;;  *)break ;;  esac  完成 

如果[-z“$ 1”]; 然后 echo用法:$ 0 [-h] [-n] [-r] files ...  exit 1  fi 

LOWER ='abcdefghijklmnopqrstuvwxyz'UPPER  ='ABCDEFGHIJKLMNOPQRSTUVWXYZ' 

case  * basename $ 0` in * upper *)TO = $ UPPER; FROM = $ LOWER ;;  *)FROM = $ UPPER; TO = $ LOWER ;;  ESAC 
 eval $ finder | sed -n' 
#刪除所有尾部斜杠 s / \ / * $ // 

#添加./如果沒有路徑,只有文件名 / \ //!小號/^/.\// 

#save path + filename  h 

 #remove path s /.*///// 

#僅轉換文件名 y /'$ FROM'/'$ TO'/ 

#now line包含原始路徑+文件,而 #個空格包含新的文件名 x 

#將轉換的文件名添加到行,現在包含 #path / file-name \ nconverted-file-name  G 

#檢查轉換的文件名是否等于原始文件名, #如果是,請不要打印任何 /^.*\/\(.*\)\n\1/b 

#轉義shell 特殊字符s / [“$`\\] / \\&/ g 

#now,將路徑/ fromfile \ n轉換為 #mv path / fromfile path / tofile并打印 s / ^ \(。* \ / \)\(。* \)\ n \(。* \)$ / mv “\ 1 \ 2”“\ 1 \ 3”/ p 
 '| $ apply_cmd 

7.5打印bash環境

該腳本從setBourne-shell命令的輸出中剝離shell函數的定義

#!/ bin / sh的 
set | sed -n'  :x 

#如果沒有發生'=()'打印并加載下一行 / =()/!{p; b; }  /()$ /!{p; b; } 

#可能啟動函數部分 #保存行,以防萬一這是一個var像FOO =“()”  h 

#如果下一行有一個括號,我們退出,因為 #沒有任何東西在函數 n  / ^ {/ q之后 

打印舊行 x; p 

現在在新線上工作 x; bx  ' 

7.6線的反轉字符

該腳本可用于反轉行中字符的位置。該技術一次移動兩個字符,因此它比更直觀的實現更快。

注意tx在標簽定義之前命令。這通常需要重置由該t命令測試的標志

想象力的讀者將會找到這個腳本的用法。一個例子是扭轉輸出banner9

#!/ usr / bin / sed -f   /../!b 
#反轉一行 開始在兩個換行符之間嵌入行 s /^.*$/ \  &\  / 

#移動第一個字符在結尾。正則表達式匹配直到 #在標記之間有零個或一個字符 tx  :x  s / \(\ n。\)\(。* \)\(。\ n \)/ \ 3 \ 2 \ 1 /  tx 

#刪除換行符 s / \ n // g 

7.7跨多行的文本搜索

本節使用ND命令來搜索跨越多行連續字。參見多線技術

這些例子涉及在文件中發現雙重發生的詞語。

在一行中尋找重復的單詞是容易使用GNU grep 和類似地用GNU sed

$ cat two-cities-dup1.txt  這是最好的時代, 這是最糟糕的時代, 那是智慧的年齡, 那是愚昧的年齡,  $ grep -E'\ b(\ w +)\ s + \ 1 \ b'two-cities-dup1.txt  它是智慧的年齡,  $ grep -n -E'\ b(\ w +)\ s + \ 1 \ b'two-cities-dup1.txt  3:這是智慧的年齡,  $ sed -En'/ \ b(\ w +)\ s + \ 1 \ b / p'two-cities-dup1.txt  它是智慧的年齡,  $ sed -En' \ b(\ w +)\ s + \ 1 \ b / {=; p}'two-cities-dup1.txt  3  這是智慧的時代, 
  • 正則表達式“\ B \ W + \ S +搜索字邊界('\ b'),后跟一個或多個字符('\ w +'),其次是空格('\ S +“)。請參閱regexp擴展
  • 在“(\ W +)'表達式創建一個子表達式。正則表達式模式'(PATTERN)\ S + \ 1'定義一個子表達式(在括號中),后跟一個由空白分隔的反向引用。成功的比賽意味著PATTERN連續重復兩次。請參閱反向引用和子表達式
  • 詞語表達式('\ b')在兩端確保部分單詞不匹配(例如'那時候'不是所需的匹配)。
  • 該 -E選項啟用擴展正則表達式語法,減輕了在括號之前添加反斜杠的需要。請參閱ERE語法

當雙字跨越兩行時,上述正則表達式將不會找到它們grepsed逐行操作。

通過使用ND命令,sed可以在多行上應用正則表達式(即,多行存儲在模式空間中,正則表達式在其上工作):

$ cat two-cities-dup2.txt  這是最好的時代,這是 最糟糕的時代,那就是 智慧的時代, 那是愚昧的時代,  $ sed -En'{N; / \ b(\ w +)\ s + \ 1 \ b / {=; p}; D}'兩城 -  dup2.txt  3  最糟糕的時候,那是 智慧的時代, 
  • N命令將下一行添加到模式空間(從而確保它在每個循環中包含兩個連續的行)。
  • 正則表達式使用'\ S +'用于與空格和換行匹配的單詞分隔符。
  • 正則表達式匹配,整個圖案空間打印p默認情況下不會打印行-n 選項。
  • 所述D去除所述圖案空間的第一行(直到第一行),它準備好用于下一個循環。

請參閱GNU coreutils手冊使用的替代解決方案 tr -suniq在 https://gnu.org/s/coreutils/manual/html_node/Squeezing-and-deleting.html


7.8線長調整

本節使用ND命令來搜索跨越多行的連續詞,以及b分支命令。請參閱多線技術分支和流控制

這些(有些設計的)示例處理以下輸入文件的格式和文字行:

$ cat two-cities-mix.txt  這是最好的時代,這是 最糟糕的時代,那 智慧的時代 愚蠢 的時代 

以下命令將換行為40個字符:

$ sed -E':x {N; s / \ n / / g; s /(。{40,40})/ \ 1 \ n /; / \ n /!bx; P; D}'\  two-cities-mix.txt  這是最好的時代,這是時代的曙光,是 智慧的時代,我 是愚蠢的時代, 

以下命令將用逗號分隔行:

$ sed -E':x {N; s / \ n / / g; s /,/,\ n /; / \ n /!bx; s / ^ * //; P; D“'\  two-cities-mix.txt  這是最好的時代, 這是最糟糕的時代, 那是智慧的時代, 那是愚昧的時代, 

兩個示例使用類似的結構:

  • :X“是一個標簽。b命令后面將使用該命令跳轉到sed程序的開頭,而不必開始新的循環。
  • ?'命令從輸入文件中讀取下一行,并將其附加到模式空間的現有內容(在其前面帶有換行符)。
  • 首先 's / \ n / / g'命令用空格替換所有換行符,丟棄輸入文件的行結構。
  • 第二 '小號///'命令根據所需的模式添加換行符(在第一個示例中為40個字符之后,第二個示例中為逗號后的字符)。
  • / \ n /!BX'命令在模式空間中搜索換行符('/ N /'),如果沒有找到(''),分支(=跳轉)到先前定義的標簽'X”。這將導致sed 在此循環中讀取下一行而不處理任何進一步的命令。
  • 如果在模式空間中找到換行符,P則用于打印到換行符(即新結構化行),然后D 刪除直到換行符的模式空間,并啟動新的循環。

7.9文件的反向行

這一個開始一系列完全無用(但有趣的)腳本,仿效各種Unix命令。這尤其是一種tac工作。

請注意,在GNU 以外的實現中,sed 此腳本可能容易溢出內部緩沖區。

#!/ usr / bin / sed -nf   #反轉所有行輸入,即第一行成為最后,... 
#從第二行,緩沖區(其中包含所有以前的行) #是*附加*到當前行,所以順序將被反轉 1!G 

#在最后一行我們完成了 - 打印一切 $ p 

#店面的一切對緩沖區再次 ^ h 

7.10編號

這個腳本取代““; 實際上它的輸出格式與GNU cat一樣。

當然這是完全沒用的,有兩個原因:第一,因為別人在C中做到了,其次,因為以下Bourne-shell腳本可以用于相同的目的,而且會更快:

#!/ bin / sh  sed -e“=”$ @ | sed -e  的/ ^ / /  N  s / ^ * \(...... \)\ n / \ 1 /  ' 

它用于sed打印行號,然后使用兩行二行N當然,這個腳本不會像下面那樣教導。

用于遞增的算法使用兩個緩沖區,因此該行將盡快打印,然后被丟棄。數字被分割,以便改變數字進入緩沖區,不變的數字進入另一個; 更改的數字將在一個步驟中修改(使用y命令)。然后將下一行的行號組合并存儲在保留空間中,以便在下一次迭代中使用。

#!/ usr / bin / sed -nf 
#在第一行 排出 x / ^ $ / s /^.*$/ 1 / 

#在模式 G  h 之前添加正確的行號 

#格式化并打印 s / ^ / /  s / ^ * \(...... \)\ n / \ 1 / p 

#從保留空間獲取行號; 加一個零 #如果我們要在下一行添加一個數字 S / \ n * $ //  / ^ 9 * $ / S / ^ / 0 / 

#單獨更改/不變的數字與x  s / .9 * $ / x& 

#持續更改位數 h  s /^.* x //  y / 0123456789/1234567890 /  x 

#在模式空間中保持不變的數字 s / x。* $ // 

#組成新的數字,刪除由G  G  s / \ n //  h 隱式添加的換行符 

7.11編號非空行

仿效'貓-b幾乎和'' - 我們只需要選擇哪些行被編號,哪些不是。

該腳本和前一個腳本通用的部分沒有評論,以顯示sed 正確注釋腳本的 重要性

#!/ usr / bin / sed -nf 
/ ^ $ / {  p  b  } 

#與cat -n從現在相同 x  / ^ $ / s /^.*$/ 1 /  G  h  s / ^ / /  s / ^ * \(...... \)\ n / \ 1 / p  x  s / \ n。* $ //  / ^ 9 * $ / s / ^ / 0 /  s / .9 * $ / x&/  h  s /^.* x //  y / 0123456789/1234567890 /  x  s / x 。* $ //  G  s / \ n //  h 

7.12計數字符

這個腳本顯示了另一種做算術的方式sed在這種情況下,我們必須添加大量數字,因此以連續的增量來實現這一點并不可行(并且可能比這個腳本更復雜)。

方法是將數字映射到字母,實現一種算盤sed一個是單位,'b幾十個等等,我們只需將當前行的字符數加上單位,然后將進位數傳播到數十,數百等。

像往常一樣,運行總計保持在保持空間。

在最后一行,我們將算盤轉換為十進制。為了多種多樣,這是一個循環而不是約80個s命令10:首先我們轉換單位,刪除'一個來自數字; 然后我們旋轉字母,使幾十變成“一個等等,直到不再有信件。

#!/ usr / bin / sed -nf 
#添加n + 1 a來保存空格(+1為換行符) s /./ a / g  H  x  s / \ n / a / 

#做進位。經t和b的是沒有必要的, #但他們加快東西 TA  :一個; S / AAAAAAAAAA / b / g的; TB; b完成 :b; S / bbbbbbbbbb / C / G; TC; b完成 :c S / CCCCCCCCCC / D / G; TD; b完成 :d S / DDDDDDDDDD / E / G; TE; b完成 :e S / eeeeeeeeee / F / G; TF; b完成 :f S / ffffffffff /克/克; TG; b完成 :g; S / GGGGGGGGGG /小時/克; 位; b完成 :h S / hhhhhhhhhh //克 

:完成 $!{  h  b  } 
 #在最后一行,轉換回十進制 
:loop  / a /!s / [bh] * /&0 /  s / aaaaaaaaa / 9 /  s / aaaaaaaa / 8 /  s / aaaaaaa / 7 /  s / aaaaaa / 6 /  s / aaaaa / 5 /  s / aaaa / 4 /  s / aaa / 3 /  s / aa / 2 /  s / a / 1 / 

:next  y / bcdefgh / abcdefg /  / [ah] / b loop  p 

7.13計數單詞

這個腳本與前一個腳本幾乎相同,一旦這行上的每個單詞被轉換成一個單一的“一個'(在前面的腳本中,每封信都改為“一個“)。

有趣的是,真正的wc程序已經為“wc -c',所以他們在計數單詞而不是字符時慢得多。相反,這個腳本的瓶頸是算術運算,因此字數計數更快(必須管理較小的數字)。

再次,公共部分沒有評論,以顯示評論sed腳本的重要性

#!/ usr / bin / sed -nf 
#將單詞轉換為 s / [ tab] [ tab] * / / g  s / ^ / /  s / [^] [^] * / a / g  s / // g 

#追加它們以容納空格 H  x  s / \ n // 

#從這里,它與wc -c相同。 / AAAAAAAAAA /!BX; s / aaaaaaaaaa / b / g  / bbbbbbbbbb /!BX; s / bbbbbbbbbb / c / g  / cccccccccc /!BX; s / cccccccccc / d / g  / dddddddddd /!BX; s / dddddddddd / e / g  / eeeeeeeeee /!BX; s / eeeeeeeeee / f / g  / ffffffffff / BX; s / ffffffffff / g / g  / ggggggggg / BX; s / ggggggggg / h / g  s / hhhhhhhhhhh // g  :x  $!{ H; b; }  :y  / a /!s / [bh] * /&0 /  s / aaaaaaaaa / 9 /  s / aaaaaaaa / 8 /  s / aaaaaaa / 7 /  s / aaaaaa / 6 /  s / aaaaa / 5 /  s / aaaa / 4 /  s / aaa / 3 /  s / aa / 2 /  s / a / 1 /  y / bcdefgh / abcdefg /  / [ah] / by  p 

7.14計數線

現在沒有什么奇怪的事情,因為sed給我們'wc -l'功能免費!看:

#!/ usr / bin / sed -nf  $ = 



7.15打印第一行

這個腳本可能是最簡單的有用sed腳本。顯示前10行輸入; 顯示的行數正好在q命令之前

#!/ usr / bin / sed -f  10q 

7.16打印最后一行

打印最后的n行而不是第一行更復雜,但確實可能。 n在第二行編碼,在爆炸字符之前。

該腳本類似于tac腳本,它將最終輸出保留在保留空間中,并將其打印到最后:

#!/ usr / bin / sed -nf 
1!{; H; G; }  1,10!s / [^ \ n] * \ n //  $ p  h 

主要是腳本保持10行的窗口,并通過添加一行并刪除最舊的(第二行的替換命令像D命令一樣工作但不重新啟動循環)來滑動它

“滑動窗口”技術是編寫高效和復雜sed腳本的非常強大的方式,因為像P手動執行的命令 需要大量的工作。

為了介紹這一技術,在本章的其余部分中得到充分的闡述NP 并且基于這一點D命令,這里是一個tail 使用簡單的“滑動窗口” 的實現

這看起來很復雜,但實際上工作與最后一個腳本相同:在我們踢了適當數量的行后,我們停止使用保持空間來保持跨行狀態,而是使用ND滑動模式空間一行:

#!/ usr / bin / sed -f 
1h  2,10 {; H; G; }  $ q  1,9d  N  D 

注意在前十行輸入之后,第一行,第二行和第四行如何處于非活動狀態。之后,所有的腳本都是:退出最后一行輸入,將下一個輸入行附加到模式空間,并刪除第一行。


7.17使重復行獨特

這是在本領域使用的一個例子NP 和D命令,可能是最難以掌握。

#!/ usr / bin / sed -f  h 

:b  #在最后一行打印并退出 $ b  N  /^\(.*\)\n\1$/ {  #兩行相同。撤消#n  命令的效果 g  bb  } 

#如果N命令添加了最后一行,請打印并退出 $ b 

線條不一樣; 打印第一個,然后回去 #在第二個工作。 P  D 

可以看到,我們使用P維護一個2行窗口D這種技術常用于高級sed腳本。


7.18打印輸入的重復行

此腳本僅打印重復的行,如“uniq -d”。

#!/ usr / bin / sed -nf 
$ b  N  /^\(.*\)\n\1$/ {  #打印第一個重復行 s /.* \ n //  p 

 #循環直到我們得到一個不同的行 :b  $ b  N  /^\(.*\)\n\1$/ {  s /.* \ n //  bb  }  } 

#最后一行不能跟著重復的 $ b 

#找到不同的。將它單獨放在模式空間 #中,并返回到頂部,狩獵其重復的 D 

7.19刪除所有重復的行

此腳本僅打印獨特的行,如“uniq -u”。

#!/ usr / bin / sed -f 
#搜索一個重復的行---直到那個,打印你找到的。 $ b  N  /^\(.*\)\n\1$/!{  P  D  } 

:c  #在模式空間中有兩條相等的行。 文件#端,我們只需退出 $ d 

#否則,我們繼續讀取行,N直到我們 找到不同的一個/  /。* \ n //  N  /^\(.*\)\n\1$/ {  bc  } 

#刪除重復行的最后一個實例,然后返回到頂部 D 

7.20擠壓空白線

作為最后一個例子,這里有三個腳本,其復雜性和速度越來越高,實現與““那就是擠壓空白線。

第一個在開始和結尾留下一個空白行,如果有一些已經。

#!/ usr / bin / sed -f 
#在空行,加入下一個 #注意在regexp中有一個明星 :x  / ^ \ n * $ / {  N  bx  } 

#現在,擠都'\ n',這也可以通過做: #s / ^ \(\ n \)* / \ 1 /  S / \ n * / \  / 

這一個有點復雜,并在開頭刪除所有空行。如果一個人在那里,它將在最后留下一條空白行。

#!/ usr / bin / sed -f 
#刪除所有前導空行 1,/ ^。/ {  /./!d  } 

#在我們刪除它,下面所有的空行 #空行,但一個 :X  !/./ {  ?  S / ^ \ n $ //  TX  } 

這將刪除前導和尾隨空白行。它也是最快的。需要注意的是回路完全做到n和 b,而不依賴于sed在一行結束時自動重新啟動腳本。

#!/ usr / bin / sed -nf 
 #delete all(leading)blanks /./!d 

#到這里:所以有一個非空 :x  #打印它 p  #得到下一個 n  #有chars?再次打印,等...  /./bx 

#不,沒有字符:有一個空行 :z  #get next,如果最后一行我們完成這里,所以沒有尾隨 #空行寫 n  #也是空的?然后忽略它,并獲得下一個...這將 #刪除所有空行 /./!bz 

#所有空行都被刪除/忽略,但我們有一個非空。因為 #我們想做的是擠壓,人為地插入一個空白行 \ 
 BX 

GNU sed的限制和不受限制

對于那些想要編寫可移植sed腳本的人,請注意,已知某些實現將線路長度(對于模式和保持空間)限制為不超過4000字節。POSIX標準規定,符合sed 實現應支持至少8192米字節行的長度。 GNU sed在線長度上沒有內置限制; 只要它可以malloc()更多(虛擬)內存,只要你喜歡,你可以喂養或構建線條。

然而,遞歸用于處理子模式和無限期重復。這意味著可用的堆棧空間可能會限制某些模式可以處理的緩沖區的大小。


9其他資源學習關于 sed

有關GNU的 最新信息,sed請訪問https://www.gnu.org/software/sed/

sed-devel@gnu.org發送一般問題和建議請訪問https://lists.gnu.org/archive/html/sed-devel/過去討論的郵件列表存檔 

以下資源提供有關sed (GNU sed和其他變體)的信息。注意這些不由GNU sed開發人員維護 

  • sed $HOMEhttp : //sed.sf.net
  • sed常見問題:http : //sed.sf.net/sedfaq.html
  • seder's grabbag:http ://sed.sf.net/grabbag
  • sed-users斯文Guckes維護郵件列表: http://groups.yahoo.com/group/sed-users/ (注意,這是不是GNU sed郵件列表)。


10報告錯誤

bug-sed@gnu.org發送錯誤報告另外,請輸入“sed -version“在你的報告的正文,如果可能的話。

請不要發送這樣的錯誤報告:

同時構建frobme-1.3.4 $ configure 錯誤→sed:文件sedscr第1行:未知選項為's' 

如果GNU sed沒有配置您喜歡的軟件包,請花幾分鐘時間來確定具體問題,并進行獨立測試。與其他程序(如C編譯器)不同,使這樣的測試用例sed非常簡單。

一個獨立的測試用例包括執行測試所需的所有數據,特定的調用sed會導致該問題。獨立測試用例越小越好。測試用例不應該包含遠離sed“嘗試配置frobme-1.3.4”的內容。是的,這在原則上是足夠的信息來尋找錯誤,但這不是一個非常實際的前景。

以下是幾個常見的錯誤,不是錯誤。


N 命令在最后一行

大多數版本的sed退出,而不是N在文件的最后一行發出命令時打印任何東西。 GNU sed在退出前打印模式空間,除非-n指定命令開關。這個選擇是設計的。

默認行為(gnu擴展名,非POSIX符合):

$ seq 3 | sed N  1  2  3 

強制符合POSIX的行為:

$ seq 3 | sed --posix N  1  2 

例如,行為

sed N foo吧 

將取決于foo是否具有偶數或奇數行11或者,在編寫腳本以閱讀模式匹配后的下幾行時,傳統的實現sed將迫使您編寫類似的東西

/ foo / {$!N; !$ N; !$ N; !$ N; !$ N; !$ N; !$ N; !$ N; $!N} 

而不是只是

/ foo / {N; N; N; N; N; N; N; N; N; } 

在任何情況下,最簡單的解決方法是$d;N在依賴于傳統行為的腳本中使用,或將POSIXLY_CORRECT變量設置為非空值。

正則表達式語法沖突(反斜杠問題)

sed使用POSIX基本正則表達式語法。根據標準,這種語法中的一些轉義序列的含義是未定義的; 在顯著的情況sed\|, \+\?\`\'\<, \>\b\B\w,和\W

使用POSIX基本正則表達式的所有GNU程序中將這些轉義序列解釋為特殊字符。所以,匹配一個或多個出現的'sedx\+X”。 abc\|def匹配“ABC' 要么 '高清”。

運行為其他人編寫的腳本時,此語法可能會導致問題 sed一些sed程序已經被寫入,假設\|\+匹配文字字符 |+這些腳本必須通過他們是否與現代實現使用去除偽反斜杠進行修改sed,如 GNU sed

另一方面,一些腳本使用s | abc \ | def || g來刪除任何一個 abcdef雖然這樣工作,直到 sed4.0.x,較新的版本解釋為刪除字符串abc|def這根據POSIX再次是未定義的行為 ,而且這種解釋可以說更具有魯棒性:比較老 sed的,例如,要求正則表達式匹配器被解析 \//常見的逃避斜杠的情況,這又是未定義的行為; 新的行為避免了這一點,這是很好的,因為正則表達式匹配器只是在我們的控制之下。


此外,該版本的sed支持幾個轉義字符(其中一些是多字符)插入非打印字符的腳本(\a\c\d\o\r, \t\v\x)。這些可能會導致與其他人編寫的腳本類似的問題sed

-一世 clobbers只讀文件

簡而言之, 'sed -i'將讓你刪除一個只讀文件的內容,一般來說 -一世選項(請參閱調用)可以讓您破壞受保護的文件。這不是一個bug,而是Unix文件系統的工作原理。

對文件的權限說明了該文件中的數據可能發生的情況,而目錄上的權限則說明該目錄中的文件列表會發生什么。sed -i“不會打開寫入已經在磁盤上的文件。相反,它將在最終重新命名為原始名稱的臨時文件中工作:如果您重命名或刪除文件,則實際上是修改目錄的內容,因此操作取決于目錄的權限,而不是文件。出于同樣的原因,sed不讓你使用-一世 在只讀目錄中的可寫文件上,并且將在打破硬鏈接或符號鏈接時 -一世 用于這樣的文件。

0a 不工作(給出錯誤)

沒有第0行。0是一個特殊地址,僅用于處理腳本啟動時的活動狀態:如果您寫入,并且第一行包含“0,/RE/1,/abc/dABC',那么該匹配將被忽略,因為地址范圍必須至少跨越兩行(禁止文件的結尾); 但你可能想要刪除的每一行,直到第一個包括'ABC',這是獲得的0,/abc/d

[a-z] 不區分大小寫

你遇到地方的問題。POSIX要求[a-z] 使用當前語言環境的歸類順序 - 在C語言中,這意味著使用 strcoll(3)而不是strcmp(3)某些區域設置具有不區分大小寫的排序規則,而其他區域設置則沒有。

另一個問題是[a-z]嘗試使用排序規則符號。這只會在GNU系統上使用 GNU libc的正則表達式匹配器而不是編譯GNU sed 提供的一個例如,在丹麥地區,正則表達式^[a-z]$匹配字符串'AA',因為這是一個單一的整理符號,一個'和'之前'b“; “在西班牙語區域中的行為類似,或者”IJ“在荷蘭語區域。

要解決這些問題,這可能會導致錯誤的shell腳本,設置LC_COLLATELC_CTYPE環境變量“C”。

s/.*// 不清除圖案空間

如果您的輸入流包含無效的多字節序列,則會發生這種情況。 POSIX要求這樣的序列匹配“', 以便 '小號/.*//“不會像你所期望的那樣清除模式空間。實際上,在大多數多字節語言環境(包括UTF-8語言環境)中,沒有辦法在腳本中間清除sed的緩沖區。因此,GNU sed提供了一個'z'命令(用于'zap')作為擴展名。

要解決這些問題,這可能會導致錯誤的shell腳本,設置LC_COLLATELC_CTYPE環境變量“C”。


附錄A GNU自由文件許可證

版本1.3,2008年11月3日
版權所有©2000,2001,2002,2007,2008 Free Software Foundation,Inc. http://fsf.org/  每個人都可以復制和分發 本許可證文件的逐字副本,但不允許更改。 
  1. 前言

    本許可證的目的是使自由的手冊,教科書或其他功能和有用的文件免費:確保每個人有效地自由地復制和重新分發它,無論是否在商業上或非商業上進行修改。其次,本許可證保留作者和出版商一種獲得他們工作信譽的方式,而不被認為對其他人作出的修改負責。

    本許可證是一種“copyleft”,這意味著文件的衍生作品本身就是同樣的自由。它補充了GNU通用公共許可證,該許可證是為免費軟件設計的Copyleft許可證。

    我們設計了此許可證,以便將其用于免費軟件手冊,因為免費軟件需要免費的文檔:免費程序應隨手冊一起提供與軟件相同的自由。但本許可證不限于軟件手冊; 它可以用于任何文本作品,無論主題或是否作為印刷本出版。我們建議本許可證主要用于作為指導或參考的作品。

  2. 適用性和定義

    本許可證適用于任何包含著作權人聲明可以根據本許可證條款分發的任何媒體的任何手冊或其他作品。此類通知授予全球無限制使用許可證,持續時間無限制,在本文所述條件下使用該工作。以下“文件”是指任何此類手冊或作品。任何公眾人士都是被許可人,被視為“你”。如果您以根據版權法許可的方式復制,修改或分發作品,則您接受許可。

    “文件”的“修改版本”是指包含文檔或其一部分的任何作品,無論是逐字復制還是修改和/或翻譯成其他語言。

    “中學部分”是本文件的命名附錄或文件的前身部分,專門處理文檔的出版者或作者與文檔的整體主題(或相關事宜)的關系,并且不包含任何可能直接落入的內容在整個科目內。(因此,如果文件部分是數學教科書,則中學部分可能不會解釋任何數學。)這種關系可能是與主題或相關事項或法律,商業,哲學,倫理學的歷史聯系的問題或政治立場。

    “不變部分”是指根據本許可證發布文件的通知中指定的標題為“不變部分”的某些輔助部分。如果一節不符合以上定義的Secondary,則不允許將其指定為Invariant。文件可能包含零個不變部分。如果文檔沒有標識任何不變的部分,那么沒有。

    “封面文本”是指在文件根據本許可證發布的通知中列出的文本的一些簡短段落作為封面文本或封底文本。封面文本最多可以有5個字,封底文字最多可以有25個字。

    文件的“透明”副本是指一種機器可讀的副本,以規范可供公眾使用的格式表示,適用于使用通用文本編輯器直接修改文檔,或(對于由像素組成的圖像)通用繪畫程序或(用于圖紙)一些廣泛可用的繪圖編輯器,并且適用于輸入文本格式化器或自動翻譯成適合于輸入到文本格式化器的各種格式。以其他透明文件格式制作的副本不是透明的,其標記或不存在標記已被安排來阻止或阻止讀者的后續修改。如果用于任何大量的文本,圖像格式不是透明的。不透明的副本稱為“不透明”。

    透明副本的適用格式示例包括無標記的純ASCII,Texinfo輸入格式,LaTeX輸入格式,使用公開可用DTD的SGML或XML,以及為人為修改設計的符合標準的簡單HTML,PostScript或PDF。透明圖像格式的示例包括PNG,XCF和JPG。不透明格式包括專有格式,只能由專有字處理器,SGML或XML(通常不可用的DTD和/或處理工具)以及由某些字處理程序生成的機器生成的HTML,PostScript或PDF輸出目的。

    “標題頁”是指對于印刷的書籍,標題頁面本身,以及需要容易地保存本許可證要求在標題頁中顯示的材料的以下頁面。對于沒有任何標題頁的格式的作品,“標題頁”是指在文本正文開頭之前,最突出的工作標題外觀的文字。

    “出版商”是指將文件副本分發給公眾的任何個人或實體。

    “被命名的XYZ”部分是指文件的命名子單元,其標題或者是精確的XYZ,或者在以另一種語言翻譯XYZ的文本之后的括號中包含XYZ。(這里XYZ表示下面提到的特定部分名稱,例如“鳴謝”,“奉獻”,“認可”或“歷史”)。當您修改文檔時,要保留此部分的“保留標題”,意味著根據這個定義,它仍然是一個“被命名的XYZ”部分。

    該文件可能包括聲明本許可證適用于文檔的通知旁的保修免責聲明。這些保修條款免責聲明被視為在本許可證中被引用參考,但僅限于免責聲明:本免責聲明可能存在的任何其他含義無效,對本許可證的含義沒有任何影響。

  3. VERBATIM復制

    只要本許可證,版權聲明和許可證聲明對本文件適用的所有副本都被復制,并且不添加任何其他條件,您可以以任何媒體(商業或非商業)復制和分發文檔。對本許可證。您不得使用技術措施阻止或控制您制作或分發的副本的閱讀或進一步復制。但是,您可以接受補償以換取副本。如果您分發足夠數量的副本,您還必須遵守第3節中的條件。

    您也可以在上述相同條件下借出副本,您可以公開顯示副本。

  4. 復制數量

    如果您發布文件的印刷版本(或通常印有封面的印刷品),編號超過100份,文件許可證通知要求封面文本,則必須將復印件全部包含在所有這些封面文本:前蓋上的封面文本和封底上的封底文本。這兩個封面也必須清楚和清晰地識別出您是這些副本的發行人。前蓋必須呈現標題的所有單詞,同樣突出和可見。另外,您還可以在封面上添加其他材料。復制限于封面的變更,只要保存文件的標題并滿足這些條件,就可以在其他方面視為逐字復制。

    如果任何一個封面所需的文本太龐大,無法容易地清理,您應該將列出的第一個(合理合理地放置)放在實際封面上,并將其余部分繼續留在相鄰的頁面上。

    如果您發布或分發文檔編號超過100的不透明副本,則必須包含機器可讀的透明副本以及每個不透明的副本,或者在每個不透明的副本中或每個不透明的副本中指定一個計算機網絡位置,使用公眾可以使用公共標準網絡協議進行下載,完整的透明文件副本,免費添加資料。如果您使用后一個選項,您必須采取相當謹慎的步驟,當您開始分發不透明份數量時,以確保此透明副本將保留在指定的位置,直到上一次分發后至少一年該版本的公開副本(直接或通過您的代理商或零售商)。

    請求但不要求您在重新分發大量副本之前聯系文檔的作者,以便他們有機會為您提供文檔的更新版本。

  5. MODIFICATIONS

    您可以在上述第2節和第3節的條件下復制和分發文檔的修改版本,前提是您根據本許可證發布修改版本,修改版本填寫了文檔的作用,從而授權分發和修改修改版本給誰擁有它的副本。此外,您必須在修改版本中執行以下操作:

    1. 在標題頁(和封面,如果有的話)中使用不同于文檔的標題以及以前版本的標題(如果有的話,應該在文檔的“歷史”部分中列出)。如果該版本的原始發行者有權限,則可以使用與之前版本相同的標題。
    2. 作為作者,標題頁上列出了一個或多個負責修改版本修改的作者的個人或實體,連同文件的主要作者(所有主要作者,如果它少于五),除非他們釋放你的這個要求。
    3. 作為發布商,“標題”頁面上的“修改版本”的發布者的名稱。
    4. 保留文件的所有版權聲明。
    5. 為其他版權聲明附近的修改添加適當的版權聲明。
    6. 在版權聲明后立即包括根據本許可證的條款授予公眾許可使用修改版本的許可證通知,其格式如下面的附錄所示。
    7. 在該許可證中保留通知文件許可證通知中給出的不變部分和所需封面文本的完整列表。
    8. 包括本許可證未經修改的副本。
    9. 保留標題為“歷史”的部分,保留其標題,并添加一個項目,至少標明標題頁上給出的修改版本的標題,年份,新作者和發行人。如果文檔中沒有“文檔”中的“歷史”部分,請在其標題頁面上創建一個說明文檔的標題,年份,作者和出版者,然后添加描述上一句所述的修改版本的項目。
    10. 保留文檔中給出的網絡位置(如果有的話)以公開訪問文檔的透明副本,以及文檔中給出的基于之前版本的網絡位置。這些可以放在“歷史”部分。您可以省略在文檔本身之前至少四年發布的作品的網絡位置,或者它所引用的版本的原始發行者獲得許可。
    11. 對于“致謝”或“奉獻”的任何部分,保留該部分的標題,并在該部分中保留每個貢獻者的確認和/或奉獻的所有實質和基調。
    12. 保留文件的所有不變部分,在其文本和標題中保持不變。章節編號或等效項不被視為部分標題的一部分。
    13. 刪除任何標題為“認可”的部分。此類部分可能不包括在修改版本中。
    14. 不要將任何現有部分重新標記為被授予“認可”或與任何不變部分產生沖突。
    15. 保留任何免責聲明。

    如果修改后的版本包含新的前項部分或符合二級部分的附錄,并且不包含從文檔中復制的材料,則可以選擇將這些部分中的一些或全部指定為不變量。為此,請將其標題添加到修改版本的許可證通知中的“不變部分”列表中。這些標題必須與任何其他章節標題不同。

    您可以添加一個標題為“認可”的部分,前提是它不僅包含各方修改的版本的簽注,例如同行評議的聲明,或者該文本已被組織批準為標準的權威定義。

    您可以添加一個最多五個詞的段落作為封面文本,最多可以添加25個詞作為封底文本,到修改版本的封面文本列表的末尾。通過(或通過任何一個實體的安排),可以添加前封面文本和封底文本之一的一段。如果文件已經包含了以前由您添加的同一封面的封面文本,或由代表您所代表的同一實體作出的安排,則不能添加另一封封; 但是您可以根據添加舊的發布者的明確許可來替換舊的。

    文件的作者和發行人不得通過本許可證授予使用其名稱進行宣傳或聲明或暗示認可任何修改版本的許可。

  6. 組合文件

    您可以根據本許可證發布的其他文件,根據上述第4節所定義的條款將修改后的版本合并在一起,前提是您將所有原始文檔的所有不變部分(未修改)全部包含在內,并將其全部列出作為您的許可證通知中組合工作的不變部分,并保留所有的保修免責聲明。

    組合工作只需要包含該許可證的一個副本,并且可以用單個副本替換多個相同的不變部分。如果有多個具有相同名稱但內容不同的不變部分,則通過在其末尾加上每個這樣的部分的標題,如果已知的話,則在該部分的原始作者或出版商的名稱中加上括號,否則為唯一號碼。對組合工作的許可證通知中的“不變部分”列表中的部分標題進行相同的調整。

    在組合中,您必須將各種原始文檔中的“歷史記錄”命名為“歷史記錄”。同樣組合任何標題為“致謝”的部分,以及任何題為“奉獻”的部分。您必須刪除所有標題為“認可”的部分。

  7. 收集文件

    您可以制作由本許可證下發布的“文檔”和其他文檔組成的集合,并將該許可證的各個副本替換為包含在該集合中的單個副本的各種文檔,前提是您遵循本許可證的規則在所有其他方面逐字復制每份文件。

    您可以從此類集合中提取單個文檔,并根據本許可證單獨分發該文檔,前提是您將本許可證的副本插入到提取的文檔中,并按照本許可證在所有其他方面逐字復制該文檔。

  8. 積極參與獨立工作

    如果由匯編而產生的版權不用于限制合法權利,則將文件或其衍生物與其他單獨和獨立的文件或作品在一個或多個存儲或分發介質中或之間的匯編稱為“匯總”的編輯用戶超出了個人作品允許的范圍。當文檔包含在合并中時,本許可證不適用于本身并非本文的衍生作品的其他作品。

    如果第3條的封面文本要求適用于文件的這些副本,則如果文檔少于整個合計的一半,則文檔的封面文本可以放置在合并中的文檔的封面上,或者如果文件是電子形式的電子等效的封面。否則,它們必須出現在打印的整個聚合體上。

  9. 翻譯

    翻譯被認為是一種修改,因此您可以根據第4節的條款分發文檔的翻譯。使用翻譯替換不變部分需要其版權所有者的特別許可,但您可以包括部分或所有不變部分的翻譯,以及這些不變部分的原始版本。您可以包括本許可證的翻譯,以及文檔中的所有許可證通知以及任何免責聲明,前提是您還包括本許可證的原始英文版本以及這些通知和免責聲明的原始版本。如果翻譯與本許可證的原始版本或通知或免責聲明之間存在分歧,則以原始版本為準。

    如果文件中的一部分被授予“鳴謝”,“奉獻”或“歷史”,則保留其標題(第1節)的要求(第4節)通常需要更改實際標題。

  10. 終止

    除非根據本許可證明確規定,否則您不得復制,修改,再授權或分發文檔。任何其他方式復制,修改,再授權或分發的任何操作均為無效,并將自動終止您在本許可證下的權利。

    但是,如果您停止所有違反本許可證的行為,則您的特許版權所有人的許可證將暫時恢復(a),除非和直到版權所有者明確終止您的許可,否則(b)如果版權所有者失敗在停止后60天內以合理的方式通知您違規。

    此外,如果版權所有者以合理的方式通知您違規行為,則特許版權持有人的許可將被永久恢復,這是您第一次收到該版權所有人違反本許可證(任何工作)的通知,您在收到通知后30天內解決違規行為。

    根據本節終止您的權利不會終止根據本許可證收到您的副本或權利的各方的許可。如果您的權利已被終止并未永久恢復,則收到部分或全部相同材料的副本不會給您任何使用權。

  11. 本許可證的未來版本

    自由軟件基金會可能不定期地發布新版本的GNU自由文檔許可證。這樣的新版本將在精神上類似于現在的版本,但可能會有不同的細節來解決新的問題或疑慮。見 http://www.gnu.org/copyleft/

    許可證的每個版本都有一個區別的版本號。如果“文件”指定本許可證的特定編號版本“或任何更高版本”適用于此,您可以選擇遵循指定版本或已發布的任何更新版本的條款和條件(不是作為草案)由自由軟件基金會。如果文檔沒有指定本許可證的版本號,您可以選擇自由軟件基金會發布的任何版本(不是草稿)。如果文檔指定代理可以決定是否可以使用本許可證的哪些版本,該代理的公開接受版本將永久授權您為文檔選擇該版本。

  12. 重新授權

    “大型多用戶協作站點”(或“MMC站點”)是指任何出版可作版權作品的萬維網服務器,也為任何人編輯這些作品提供了突出的設施。任何人都可以編輯的公共wiki就是這樣一個服務器的例子。網站中包含的“大規模多作者協作”(或“MMC”)是指在MMC網站上發布的任何版權作品。

    “CC-BY-SA”是指由知識共享署(Creative Commons Corporation)發布的知識共享署名 - 相同方式3.0許可協議,Creative Commons Corporation是一家在加利福尼亞州舊金山擁有主要營業地點的非營利性公司,以及未來的Copyleft版本同一組織發布的許可證。

    “合并”是指作為另一個文檔的一部分,全部或部分地發布或重新發布文檔。

    如果根據本許可證獲得許可,則MMC有資格獲得重新認證,如果根據本許可證首次發布的所有作品,除了本MMC之外的其他地方,隨后全部或部分納入MMC,(1)沒有涵蓋文本或不變部分,以及(2)因此在2008年11月1日之前被合并。

    MMC網站的運營商可以在2009年8月1日之前的任何時間,在同一網站上重新發布CC-BY-SA網站中的MMC,前提是MMC有資格獲得重新認證。

ADDENDUM:如何使用本許可證的文件

要在您所寫的文檔中使用本許可證,請在文檔中包含許可證的副本,并在標題頁面之后放置以下版權和許可證通知:

 版權(C) 年 你的名字 授權 根據GNU自由文件許可證1.3版 或自由軟件基金會發布的任何更新版本的條款復制,分發和/或修改本文檔;  沒有不變的部分,沒有封面文本,也沒有封底 文本。許可證的副本包含在標題為“GNU  Free Documentation License”的部分。 

如果您有不變章節,封面文本和封底文本,請將“with ... Texts。”替換為:

 其中不變部分列出了他們的標題 前封面文本是列表,封面文本列表

如果您沒有封面文本的不變章節,或三者的其他組合,請合并這兩種替代方案以適應這種情況。

如果您的文檔包含程序代碼的不尋常的示例,我們建議您在您選擇的免費軟件許可證(如GNU通用公共許可證)下并行發布這些示例,以允許其在自由軟件中使用。



概念指數

這是本手冊中討論的所有問題的一般索引,sed命令和命令行選項除外



向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

古田县| 台南市| 桐乡市| 娄底市| 襄汾县| 和平区| 平塘县| 诏安县| 汝南县| 千阳县| 随州市| 景洪市| 手游| 内乡县| 辽源市| 内江市| 东乡族自治县| 米易县| 合水县| 道真| 响水县| 德化县| 屯昌县| 萨嘎县| 策勒县| 五峰| 曲周县| 罗城| 西畴县| 宝鸡市| 大竹县| 南川市| 砀山县| 繁昌县| 涞水县| 马公市| 平安县| 巴中市| 抚州市| 宁城县| 墨竹工卡县|