我想用该文件中的另一个路径替换 yml 文件中的路径

i want to replace a path inside a yml file with another path in that file

我尝试使用 sed 命令替换 yml 文件中的路径,还尝试注释该文件中的旧路径。评论工作正常但不是专门针对该路径。该文件中还有其他路径。我的 yml 文件看起来像:

  enabled: true
  close_eof: true
  #close_inactive: 1h
  paths:
      - /home/directory/another_directory/directory_20200910/*_*_*

现在我希望我的文件看起来像

  enabled: true
  close_eof: true
  #close_inactive: 1h
  paths:
      - /home/directory/another_directory/directory_(today's date here-20201001)/*_*_*

请注意:yml 文件有四个空格,然后在路径前有一个“-”

SPTH='/home/directory/another_directory'
sed -e '/$SPTH/ s/^#*/#/' -i test.yml
echo - /home/directory/another_directory/directory_date +%Y%m%d >> /home/test.yml

但这似乎行不通,已经尝试过的另一件事是

sed -e '/home/ s/^#*/#/' -i test.yml
echo - /home/directory/another_directory/directory_`date +%Y%m%d` >> /home/test.yml

这很好用,但它在每个以 /home 开头的路径上添加了注释,并且还在文件末尾回显了路径。因此我必须使用 sed 来替换当前日期的路径。

如果我想用昨天的日期替换文件夹的日期,请告诉我,因为我想在文件夹创建一天后 运行 脚本。

我发现了几个问题:

首先,该正则表达式应该做什么?

正则表达式 /home/ s/^#*/#/ 将对包含 home 的所有行执行替换(很酷),但它会将行开头的任意数量的 # 替换为单身 #.

即:它将删除每行开头的所有 #,然后向每行添加一个新的(因为 ^#* 也将匹配零前导哈希)。

这可能不是您想要的。

single-quotes会阻止变量的扩展

sed -e '/$SPTH/ s/^#*/#/' 将对包含文字 $SPTH 的所有行执行替换(无论是否存在 shell 变量 SPTH 及其内容)。

这可能不是您想要的。

如果要$SPTH展开,需要double-quotes (")

(但是当然,你 运行 会遇到问题,因为 $SPTH 的扩展值包含斜线,干扰 sed-expression 本身)。

解决方案。

要简单地替换当前目录,请使用如下内容:

SPTH='/home/lt-1027'
sed \
  -e "s|^\( *-  *${SPTH}\)/.*/\*_\*_\*|/$(date +%Y%m%d)/*_*_*|" \
  -i test.yml

这里使用竖线 | 作为分隔符,以避免 ${SPTH} 中的斜杠出现问题。 它捕获文件的缩进、破折号和开头(直到 ${SPTH} 的末尾)到 capture-group </code> 中,然后用于替换,因此替换文本具有与原始缩进相同(希望保持您的 yaml 完好无损)</p> <p>如果要保留原来的路径并注释掉,使用</p> <pre><code>sed \ -e "s|^\(\( *- *${SPTH}\)/.*/\*_\*_\*\)$|#\n/$(date +%Y%m%d)/*_*_*|" \ -i test.yml

这会将整个旧行捕获到引用 </code> 中(因此我们可以通过前缀 <code># 将其替换为自身的 commented-out 版本);缩进现在被捕获到 )

对 YAML 使用简单的文本处理工具并不总是正确的。如果您知道您的 YAML 输入将始终具有特定格式,那么这样的解决方案可能是可以接受的。

假设您要替换所有出现

/home/directory/another_directory/directory_<any_number>/*_*_*

/home/directory/another_directory/directory_<today_s_date>/*_*_*

你可以使用

sed -e 's#\(/home/directory/another_directory/directory_\)[0-9]*\(/\*_\*_\*\)#'$(date +%Y%m%d)'#' test.yml

用你的例子输入这个打印

enabled: true
close_eof: true
#close_inactive: 1h
paths:
    - /home/directory/another_directory/directory_20201001/*_*_*

当然你可以使用选项-i替换输入文件而不是打印修改后的数据。 (确保 sed 命令正确运行,因为您可能会丢失原始输入数据。)

如果要求路径在变量SPTH中,脚本可以这样修改

SPTH='/home/directory/another_directory'
sed -e 's#\('$SPTH'/directory_\)[0-9]*\(/\*_\*_\*\)#'$(date +%Y%m%d)'#' test.yml

如果你想要昨天的日期而不是今天的日期,只需替换

date +%Y%m%d

date -d yesterday +%Y%m%d

此选项 -d 未由 POSIX 标准定义,但可用于 Linux 上的 GNU date

你可以试试:

date +%Y%m%d
20201001
today=$(date +%Y%m%d)
sed "s#/directory_[0-9]*#/directory_${today}#" test.yml

输出:

enabled: true
close_eof: true
#close_inactive: 1h
paths:
    - /home/directory/another_directory/directory_20201001/*_*_*

使用带有选项 -i 的 sed 来保存输出