空でない最後の行をコマンド出力に置き換える

空でない最後の行をコマンド出力に置き換える

.envこのようなファイルがあります。

PARAM1=val
PARAM2=val

空白のない最後の行を別のファイルの内容に置き換えたいと思います。

これまで私は以下を持っています:

{ (sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' local.env | sed '$d' local.env && printf "CONFIG=%s" "$(cat config.json | jq -c .)") >local.env.mod; } && mv local.env.mod local.env

これを行うより良い/簡単な方法はありますか?

答え1

ファイルを元に戻して交換できます。最初空白ではない行

printf -v new_line 'CONFIG=%s' "$(jq -c . config.json)"

tac local.env \
| awk -v line="$new_line" '
      !n && /[^[:blank:]]/ {print line; n = 1; next}
      {print}
  ' \
| tac > local.env.mod && mv local.env.mod local.env

答え2

全然知らないより良いものPARAM2(置き換える必要がある設定行であることを知っておくとよいでしょうが、具体的には「空ではない最後の行」と言われました。)しかし、ed編集者は、過度に複雑なテキストファイルに編集プロセスを適用するのに非常に上手ですsed(しかしsedこれは)とは異なり、テキストRead into memoryを置き換えることに注意してください。

$ cat new-content
this is the new content
$ printf '%s\n' '?.? d' '-r new-content' ,p Q | ed -s file
PARAM1=val
this is the new content

結果編集スクリプトedは次のとおりです。

?.? d
-r new-content
,p
Q

最初に何かが含まれている最初の行を後ろに検索してから(ここでは空白が表示されていなくても計算されます。.これは[[:graph:]]、見える文字にのみ興味があるように変更されます)、削除します。

行を削除するとカーソルが次の行に移動するため、-前のr内容はカーソルがある行の上に行の内容を挿入(読み取り)することを意味しますednew-contens

最後に、標準出力に文書全体を表示し、無条件エディタを終了します,pQ「インライン編集」を実行するには、これら2つのコマンドを変更さwqれた文書をファイルに書き直し、終了する単一のコマンドに変更します。

inの後にファイルの内容を挿入するには、new-contentファイルの末尾を空白ではなく最後の行から始めて置き換えます。=CONFIG=

$ printf '%s\n' '?[[:graph:]]?,$ c' 'CONFIG=' . 'r new-content' '-,.j' ,p Q | ed -s file
PARAM1=val
CONFIG=this is the new content

このcコマンドは行を変更します。空白ではなく、最後の行から最後まで行を置き換えるために使用します。コマンド入力はドットcで終わり、new-contentその後ろの内容が挿入されますr。このjコマンドは、CONFIG=前の行()を挿入したばかりの行に関連付けます(あなたの質問にあるので、1行と仮定します)。

関連情報