傳遞給“sed -e”的這個腳本的功能是什麼?
TL;DR- 下面的模式中發生了很多事情
sed
,我不確定離散的部分是如何組合成一個整體命令的。重擊版本:
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin21)
我正在通過逐個文件閱讀 RBENV 程式碼庫文件來學習 shell 腳本,並且我遇到了
rbenv-help
包含此函式定義的文件:extract_initial_comment_block() { sed -ne " /^#/ !{ q } s/^#$/# / /^# / { s/^# // p } " }
我看到如何在程式碼中進一步呼叫此函式,所以我知道它的第一個 arg 是文件名:
extract_initial_comment_block < "$filename" | collect_documentation
從這裡我可以看到由“$filename”表示的文件被作為標準輸入提供給
sed
命令。就我的問題而言,連鎖功能“collect_documentation”是無關緊要的。我還從函式的名稱中得知,它的目的是獲取這樣的文件,並返回其摘要和使用註釋,即連結文件的第 2-14 行。但是,我還沒有測試過這個理論,所以我可能不是 100% 正確的。
此外,我從這個 StackExchange 答案中知道,標誌的目的
-e
是告訴sed
將後續字元串解釋為命令(或由換行符分隔的命令集合?)。因此,它的主體看起來extract_initial_comment_block
包含 3 個單獨的腳本,sed
以便按順序進行解釋。相同的 StackExchange 答案說{...}
用於將命令組合在一起,但我不確定這是否是這個正則表達式(這些正則表達式?)中發生的事情。據我所知,這裡有 3 個腳本
sed
:/^#/ !{ q }
s/^#$/# /
/^# / { s/^# // p }
但是,即使在這些腳本中的每一個中,都使用了一些我無法辨識的模式(例如
^#
和),即使在利用了Linux Data Project之類的資源之後也是如此。似乎有很多動人的部分,我不確定每個腳本是如何組合成成品的。!{ q }
我試圖以盡可能清晰的方式走過我的思考過程。到目前為止,我的構想正確嗎?如果不是,我在哪裡偏離了航線?如果是,我如何推斷傳遞給的每個命令的含義
sed
?
/^#/ !{ q }
斜線之間的部分是正則表達式,其中
^
表示字元串的開頭,#
只是字元本身。該模式選擇執行相關命令的行。尾隨!
反轉匹配的意義,q
是退出的命令。因此,當 sed 程序看到不以註釋標記開頭的行時,它會退出該程序#
。s/^#$/# /
s/a/b/
s用 b 代替 a,^
是行首,$
行尾,#
是它自己。所以這改變了一行,只有一個單獨的#
到#
+空格。/^# / { s/^# // p }
如果該行以 a
#
和空格 (/^# /
) 開頭,則將和空格替換為#
空 (s/^# //
) 並列印該行 (p
)。這是以前的替換派上用場的地方。sed的
-n
選項(在命令的開頭)告訴 sed在執行腳本後不列印該行,預設情況下會這樣做。請注意,腳本會忽略以 a 開頭且
#
後面沒有空格的行,包括以它開頭的 hashbang 行#!
,告訴作業系統要為腳本使用哪個解釋器。可能是故意的,但可能會隱藏其他一些行。例如
#!/bin/sh # some script # #this is ignored # this prints # this doesn't print any more whatever
變成
some script this prints