sedの 'i\'コマンドにインデントされた引数は移植可能ですか?

sedの 'i\'コマンドにインデントされた引数は移植可能ですか?

私の印象はPOSIX仕様sedi\出力で先行スペースを望まない限り、コマンドの次の行のテキストを左揃えにする必要があります。

私の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\?)

答え1

いいえ。しかし、先行スペースを避ける限り、スクリプトは移植可能です。なぜ?一部sedはテキスト行から空白文字を削除するため、これを防ぐ唯一の方法は、前世紀のこのマニュアルページで説明したように、前のスペースを避けることです。12サム
アーカイブを確認して読み取ると、同じことが適用されますBSD sedOSXコードをコピーしただけで拡張子ではありません)。manページ:BSD 2.11非常に明確な:

(1)私\
テキスト
.......
で表されるパラメータテキスト'\'1つ以上の行で構成され、最後の行を除くすべての行は隠された改行文字で終わります。テキストのバックスラッシュは's' コマンド置換文字列でバックスラッシュとして扱われ、すべてのスクリプト行で発生する削除から初期スペースとタブを保護するために使用できます。

今、POSIX仕様のどこに文書化されていますか?ただ言う

パラメータテキストは1つ以上の行で構成する必要があります。テキストに含まれる各<newline>の前に<backslash>を付ける必要があります。テキストの他の<バックスラッシュ>文字は削除する必要があり、後続の文字は文字通り処理する必要があります。

下にスクロールすると基本的なそれは言う

コマンドラインで<空白>と<空白>文字を許可する必要があるという要件は、過去の慣行を明確に説明し、「初期空白[原文]とタブ文字が削除されないように保護する」というフレーズの混乱を排除するために、提案よりも明確になりました。 sedユーティリティのテキストを説明する多くの履歴文書に表示されます。 (すべての実装がコマンドラインでこれを許可しますが、テキスト行から<スペース>文字を削除することは知られていません。アドレスの前には先行する<スペース>文字)。

関連部分なので「バックスラッシュを使用できます。」この引用には含まれておらず、残りのフレーズは「初期のスペースを保護してください...」言うことはできません... 1


とにかく要約すると、一部の実装ではテキスト行からスペースを削除しました(そして一部はまだ実行します)。ただし、すべての実装が準拠する必要があるPOSIX仕様のため

テキストの他の<バックスラッシュ>文字は削除する必要があり、後続の文字は文字通り処理する必要があります。

挿入するテキストの行をインデントする移植可能な方法は、各行の先行スペースをエスケープすることであると結論付けることができます。


OSX1:私はまた、人々がソースコードを変更せずにページの段落全体をBSD変更する理由を理解していません。以前と同じ動作を得ますが、これを文書化するmanセクションはもう存在しません。man

答え2

標準動作ではなくOSX拡張ですsed。あなたは見ることができますこのリンクは機能的にcompile_text:

/*
 * Compile the text following an a or i command.
 */
static char *
compile_text()
{
    int asize, size;
    char *text, *p, *op, *s;
    char lbuf[_POSIX2_LINE_MAX + 1];

    asize = 2 * _POSIX2_LINE_MAX + 1;
    text = xmalloc(asize);
    size = 0;
    while (cu_fgets(lbuf, sizeof(lbuf))) {
        op = s = text + size;
        p = lbuf;
        EATSPACE();
        for (; *p; p++) {
            if (*p == '\\')
                p++;
            *s++ = *p;
        }
        size 

彼らはEATSPACEスペースを占めるためにマクロを使用します。

FreeBSDでは、 を使用するときに行連続文字でsed誤って処理され、動作がさらにおかしくなる場合があります。\私のFreeBSD 9.3では:aic

$ echo 1 | sed -e 'i\ 1'
": extra characters after \ at the end of i command

しかし:

$ echo 1 | sed -e 'i\
 2'
2
1

効果的でスペースも占めています。

GNU sed、 Heirloom にはsedこの問題はありません。

答え3

ガンガン最高の答えを与えたしかし、参考のためにここでは牛に似た一種の栄養 sedする:

echo foo | sed 'i\
     This line starts with spaces.'

出力:

     This line starts with spaces.
foo

関連情報