Sed

縮進 sed 的 ‘i’ 命令的參數是否可移植?

  • September 7, 2017

我對POSIX 規範sed的印像是,有必要在命令後面的行上左對齊文本i\,除非你想在輸出中前導空格。

在我的 Mac 上進行的快速測試(使用 BSD sed)表明這可能不是必需的:

$ cat test.sed 
#!/bin/sed -f
i\
     This line starts with spaces.
$ echo some text | sed -f test.sed
This line starts with spaces.
some text
$ 

但是,我似乎無法在任何地方找到此文件。它不在 POSIX 規範中,甚至不在sed我係統的手冊頁中。

sed我可以在我想要移植的腳本中依賴這種行為嗎? 它的便攜性如何?

(它在任何地方都有記錄嗎?


(獎勵問題:甚至可以強制sed在傳遞給的固定行的開頭插入空格i\嗎?)

不,但只要您避開任何前導空白,您的腳本就可以移植。為什麼 ?因為有些seds 從文本行中去除空白字元,避免這種情況的唯一方法是轉義前導空白,正如這些可追溯到上個世紀的手冊頁所解釋的那樣:1 , 2 , 3

也是如此BSD sedOSX只是複制了程式碼,這不是他們的副檔名),如果您檢查檔案並從中閱讀man頁面,BSD 2.11那就很清楚了:

*(1)i*

text

…….

表示為text的參數由一行或多行組成,除最後一行外,所有行都'\'以隱藏換行符結尾。文本中的反斜杠被視為's' 命令替換字元串中的反斜杠,可用於保護初始空白和製表符免受在每個腳本行上進行的剝離。

現在,這在 POSIX 規範中記錄在哪裡?它只說

參數文本應由一行或多行組成。文本中每個嵌入的 <newline> 都應以 <backslash> 開頭。文本中的其他<反斜杠>字元應刪除,後面的字元應按字面處理。

如果你在RATIONALE下向下滾動,它會說

在命令行中接受 <blank> 和 <space> 字元的要求比早期提案中的要求更加明確,以清楚地描述歷史實踐並消除對片語“保護初始空白”的混淆

$$ sic $$以及在每個腳本行上完成的剝離中的製表符”,出現在 sed 實用程序文本描述的許多歷史文件中。(並非所有實現都已知從文本行中剝離 <blank> 字元,儘管它們都有允許在命令行地址前的前導 <blank> 字元。)

由於帶有*“反斜杠可能用於”的部分未包含在該引用中,因此剩餘的片語“保護初始空白……”*沒有任何意義…… 1


無論如何,總結一下:一些實現確實(並且一些仍然這樣做)從文本行中去除空白。但是,由於所有實現都應遵守的 POSIX 規範說

文本中的其他<反斜杠>字元應刪除,後面的字元應按字面處理。

我們可以得出結論,在要插入的文本中縮進行的便攜方法是轉義每一行的前導空白。


1:我也不明白為什麼OSX/BSD人們在man不更改原始碼的情況下更改了頁面中的整個段落 - 你得到與以前相同的行為,但記錄這些內容的 man 部分不再存在。

引用自:https://unix.stackexchange.com/questions/312579