一个想法是跳过/忽略/删除带有今天日期的行(如果存在),然后添加一个带有今天日期的新行。
示例数据文件:
$ cat date.log
2021-08-14, 23.1
2021-08-15, 17.3
2021-08-16, 9.3
$ today=$(date '+%Y-%m-%d')
$ echo $today
2021-08-17
$ newvalue=13.2
一个sed的想法来实现这个逻辑:
$ sed -i -n -e "/^${today}, .*$/"'!p' -e '$a'"${today}, ${newvalue}" date.log
地点:
-
-i -n -e - -inplace 更新源文件,-n 禁止自动打印图案空间,-e 指定一段脚本
-
"/^${today}, .*$/" - 搜索匹配的模式(行首)+ ${today} + , + 其余行;需要使用双引号,以便将${today} 替换为其实际值
-
'!p' - 反向模式搜索和打印行(即,打印除与^${today}, .*$ 匹配的行之外的所有内容);需要使用单引号,因为双引号中的!p 将替换为以字母p 开头的最后一个历史命令
-
-e '$a' - 另一段找到文件结尾的脚本 ($) 和 a追加以下字符串;必须使用单引号,以便 bash 不会尝试将文字 $a 替换为变量 a 的内容
-
"${today}, ${newvalue}" - 附加到文件末尾的字符串
如果我们在 sed 调用前加上 set -xv(启用调试模式),我们会看到控制台上打印了以下内容:
+ sed -i -n -e '/^2021-08-17, .*$/!p' -e '$a2021-08-17, 13.2' date.log
还有我们文件的内容:
$ cat date.log
2021-08-14, 23.1
2021-08-15, 17.3
2021-08-16, 9.3
2021-08-17, 13.2 # new line appended to file
再运行几次(发出set +xv 以禁用调试模式后):
$ newvalue=32.7
$ sed -i -n -e "/^${today}, .*$/"'!p' -e '$a'"${today}, ${newvalue}" date.log
$ cat date.log
2021-08-14, 23.1
2021-08-15, 17.3
2021-08-16, 9.3
2021-08-17, 32.7 # updated (really deleted and appended)
$ newvalue=73.xxx
$ sed -i -n -e "/^${today}, .*$/"'!p' -e '$a'"${today}, ${newvalue}" date.log
$ cat date.log
2021-08-14, 23.1
2021-08-15, 17.3
2021-08-16, 9.3
2021-08-17, 73.xxx # updated (really deleted and appended)
$ today='2021-09-23'
$ newvalue=7.25
$ sed -i -n -e "/^${today}, .*$/"'!p' -e '$a'"${today}, ${newvalue}" date.log
$ cat date.log
2021-08-14, 23.1
2021-08-15, 17.3
2021-08-16, 9.3
2021-08-17, 73.xxx
2021-09-23, 7.25 # new line appended to file