
一致するパターンの後にいくつかのテキストを追加するときは、コンテンツの残りの部分と追加のコンテンツを分離するためにコメントを含む空白行を追加したいと思います。しかし、最初の項目では、追加を\n
使用してエスケープする必要がありましたが、追加された残りのテキストには必ずしも必要ではないことがわかりました。\
\
\\n
なぜですか?
SUSE 11サーバー(bash v3.2.57(2)およびGNU sedバージョン4.1.5)で作成した例は次のとおりです。
edwdev@hdpedge1:/edw> sed '/test/a \\nNot a test\nJust Playing' <<< test
test
Not a test
Just Playing
最初の項目をエスケープしない場合\n
(a
sedコマンドの後にN包装の代わりに印刷してください。
edwdev@hdpedge1:/edw> sed '/test/a \nNot a test\nJust Playing' <<< test
test
nNot a test
Just Playing
a
誤って代替構文と競合しないように、コマンドの後に意図的にスペースを追加しました。
\n
に変更すると、同じ動作が観察されます\t
。コマンドの後のスペースの数はa
重要ではないようです。複数のスペースがあっても特殊文字を印刷するには、最初のバックスラッシュをエスケープする必要があります。
これは最初に観察された他の環境でも同様でした。 Centos 7 x64 VM、bashバージョンは4.2.46(2)、sedバージョンはGNU sed 4.2.2でした。
sed -i '/\[mysqld\]/a \\n# <<INSERTED MANUALLY>>\ntransaction-isolation=READ-COMMITTED\ninnodb_flush_method=O_DIRECT\nmax_connections=550\n# <<END OF MANUAL INSERTIONS >>\n' /etc/my.cnf
出力:
...
[mysqld]
# <<INSERTED MANUALLY>>
transaction-isolation=READ-COMMITTED
innodb_flush_method=O_DIRECT
max_connections=550
# <<END OF MANUAL INSERTIONS >>
...
まず、出力をエスケープ解除します。\ n:
[mysqld]
n# <<INSERTED MANUALLY>>
transaction-isolation=READ-COMMITTED
innodb_flush_method=O_DIRECT
max_connections=550
# <<END OF MANUAL INSERTIONS >>
このような行動をする特別な理由はありますか?文書の閲覧中に詳細が見つかりません(ここ)、もちろん私は文書全体を徹底的に読んでいません。
答え1
基準a
命令の形sed
は
a\
text to be appended
c
コマンドとi
同じ形式に従います。
より多くの行を追加するには、各行で改行をエスケープする必要があります。
a\
text to\
be appended
標準はGNUのように改行文字を解釈する方法がsed
わからないので、GNU以外のものを使用する1行のコマンドは(in)のように書かれます。\n
sed
sed
bash
sed $'/test/a\\\n\\\nNot a test\\\nJust Playing\n' <<<test
ここでは$'...'
、シェルを使用してすべてを\n
実際の改行文字\\
と\
。
$'...'
このコマンドは次の形式で作成できますが、次の機能はありませんbash
。
sed '/test/a\
\
Not a test\
Just Playing
' <<<test
これら2つのコマンドはGNUでも機能しますsed
。
GNUはsed
さらに、前のテキストと改行文字の間に改行文字を挿入することなく追加のテキストが表示されるようにし、完全な削除をa
許可します。\
\
ただし、コマンドの直後のコマンドは、コマンドa
の標準形式でバックスラッシュとして解釈されます。a\
(これはあなたの質問の基本的な問題です)。 GNUはsed
また、スクリプトに追加されたテキストの末尾に改行を追加します。したがって、GNUを使用すると、sed
次のように書くことができます。
sed '/test/a\ \
Not a test\
Just Playing' <<<test
sed
またはGNUが知っているという事実を活用して\n
、
sed '/test/a\\nNot a test\nJust Playing' <<<test
答え2
これは正確に文書化された動作ではありませんが、すべてが拡張です。 3つの拡張類似コマンド(a
、、i
およびc
)はすべて同じように機能します。先行スペースは無視され、テキストがで始まると\
削除されます。デフォルトでは、sedが次の形式のどれを使用するかは問題ではありません。
i foo
i \foo
i \
foo
彼らはすべて同じです。 (私はi
ここに慣れていることを知っていますが、説明を確認してくださいa
。i
そしてc
それはシュールです。)
そしてパスワード次のように表示されます。
1111 case 'a':
1112 case 'i':
1113 case 'c':
1114 ch = in_nonblank ();
1115
1116 read_text_to_slash:
1117 if (ch == EOF)
1118 bad_prog (_(EXPECTED_SLASH));
1119
1120 if (ch == '\\')
1121 ch = inchar ();