sed 替换每一行而不是一行

sed 替换每一行而不是一行

我试图用由变量组成的字符串替换测试文件中的特定行号。我的问题是它似乎用字符串替换文件中的每一行,而不仅仅是特定行。

它需要是行号,因为内容经常会改变,它有点像状态文件,如果有人对如何实现这一点有更好的想法,我洗耳恭听。

本质上,当同步作业完成时,它们应该在 status.config 文件中记录每个作业的同步开始和完成时间,并且每次针对该特定作业运行同步时,它都应该覆盖当前行。

laststartline=$(grep -n '$RCLONESESSION'LastStart $scriptdirectory/$mountsconfig | awk -F: '{print $1}') ##OBTAIN LINE NUMBER FOR LAST START TIME FOR THIS SESSION


sed -i ''$laststartline's/.*/'$RCLONESESSION'LastStart:'$time'/' $scriptdirectory/$mountsconfig ##REPLACE LINE IN MOUNTS.CONFIG WITH RELEVANT TIMESTAMP FOR JOB START

任何人都可以明白为什么整个文件被内容覆盖,而不仅仅是 $laststartline 中指定的行

如果有帮助:

$RCLONESESSION is predefined as rclone2
$time is defined as the current date and time in MM-DD-YYYY-HH-MM-SS format.
$scriptdirectory is defined as /root/scripts/
$mountsconfig is defined as status.config

第 22 行是我试图替换的行,它rclone2LastStart:?应该被替换为rclone2LastStart:MM-DD-YYYY-HH-MM-SSfrom$time变量。

这需要是不同的行,具体取决于查找,因为$RCLONESESSION可能是不同的会话,并且这需要替换$mountsconfig.

我希望它在我的sed命令中是显而易见的,就好像我直接从终端运行它,而不是在我的脚本中运行一样,它会按预期替换一行。

如果它在脚本内运行,它将用参数替换每一行$time

答案1

我现在感觉自己像个傻瓜,是 $RCLONESESSION 中的 $laststartline 变量上的引号引起了问题。

laststartline=$(grep -n '$RCLONESESSION'LastStart $scriptdirectory/$mountsconfig | awk -F: '{print $1}') ##OBTAIN LINE NUMBER FOR LAST START TIME FOR THIS SESSION

需要更改为:

laststartline=$(grep -n "$RCLONESESSION"LastStart $scriptdirectory/$mountsconfig | awk -F: '{print $1}') ##OBTAIN LINE NUMBER FOR LAST START TIME FOR THIS SESSION

现在一切正常,感谢@steeldriver 的帮助。

答案2

对另一个问题的回答。 grep 不需要查找行号,因为 sed 可以搜索行本身。

sed -i '/'$RCLONESESSION'LastStart:/s/.*/'$RCLONESESSION'LastStart:'$time'/' $scriptdirectory/$mountsconfig

换句话说,不要使用行号,而是使用表达式/text/来说明将其应用到哪一行。通过将匹配应用于每一行并更有选择性地进行编辑,它可能会变得更短。

sed -i 's/\('$RCLONESESSION'LastStart:\).*/\1'$time'/' $scriptdirectory/$mountsconfig

(如果 $RCLONESESSION 不在行的开头,则更s/\(改为s/^.*\(

相关内容