
シェル スクリプトを使用して、さまざまな種類の VM をセットアップします。多くの場合、これらのスクリプトには、 を使用して構成ファイルの特定の位置に挿入する必要がある複数行の変数が含まれていますsed
。
次のように作成すれば、すべて問題ありません。
VAR="Config Line1\nConfig Line2\nConfig Line 3"
sed -i "/MatchingPattern/ a $VAR" somefile
ただし、テキスト ブロックがかなり長くなる可能性があるため、スクリプトが読みにくくなります。
次のように書くと:
VAR="Config Line1
Config Line2
Config Line 3"
sed -i "/MatchingPattern/ a $VAR" somefile
スクリプトを実行するとエラーが発生します: sed: -e expression #1, char 31: unknown command:
C'`
sed
このように宣言された変数を使用する方法はありますか?
答え1
コマンドの標準構文は次のa
とおりです。
sed -e 'a\
first line\
second line\
last line'
BSD(少なくともFreeBSDとOS/X)はsed
先頭の空白を削除します、 そして-e
バグを回避するためにGNU では、最初の行が空でない限り、sed
の直後に移動できます。a\
したがって、入力を前処理する必要があります。
VAR='content with
multiple lines
some with lead blanks
or even backslash\'
preprocessed_VAR=$(printf '%s\n' "$VAR" |
sed 's/\\/&&/g;s/^[[:blank:]]/\\&/;s/$/\\/')
sed -i -e "/MatchingPattern/a\\
${preprocessed_VAR%?}" somefile
( FreeBSD または OS/X では-i
に置き換えてください-i ''
)。
GNU/Linux および GNU シェル ( bash
) またはを使用する場合はzsh
、代わりに次のように実行できます。
sed -i '/MatchingPattern/r /dev/stdin' <<< "$VAR"
これが機能するのはbash
、zsh
削除された一時ファイルを使用して here-strings を実装し、Linux 上の /dev/stdin がファイルへのシンボリック リンクとして実装されているためです (つまり、複数回開くことができ、そのたびに先頭で開きます)。
ここでは、代わりに GNU を使用することもできますawk
。
(export VAR
gawk -i /usr/share/awk/inplace.awk '{print}; /MatchingPattern/{print ENVIRON["VAR"]}' somefile)
使ってはいけません-i inplace
は、まず現在の作業ディレクトリから拡張機能(または)gawk
をロードしようとしますが、そこに誰かがマルウェアを仕掛けている可能性があります。で提供される拡張機能のパスはシステムによって異なる場合があります。inplace
inplace
inplace.awk
inplace
gawk
gawk 'BEGIN{print ENVIRON["AWKPATH"]}'
またはperl
(その-i
由来は):
(export VAR
perl -pi -e '$_ .= "$ENV{VAR}\n" if /MatchingPattern/' somefile)
答え2
sed
このエラーは、 append コマンドa
で実際の の後にバックスラッシュが必要であるために発生しますa
。
GNUの場合sed
:
$ sed "/pattern/a\\$VAR" file.in >file.out
sed
私の知る限り、BSDでは、a
改行が適切にエスケープされていない限り、コマンドを使用してファイルに 1 行しか挿入できません。
BSD でこれを解決する方法に関する関連した回答sed
:http://unix.stackexchange.com/a/60322