我有一个.env
像这样的文件
PARAM1=val
PARAM2=val
我想用另一个文件内容替换最后一个 noblank 行
到目前为止,我有如下内容:
{ (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
) 不同:
$ 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
告诉插入(读取)光标所在行上一行ed
的内容。new-contens
最后,p
并Q
在标准输出上显示完整文档,然后无条件退出编辑器。如果要进行“内联编辑”,请将这两个命令更改为单个wq
命令,该命令将修改后的文档写回文件并退出。
要在innew-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=
) 与我们刚刚插入的行连接起来(我们假设它是一行,因为它在您的问题中)。