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

Linux 我想用yml文件中的另一个路径替换该文件中的一个路径,linux,bash,sed,scripting,yaml,Linux,Bash,Sed,Scripting,Yaml,我尝试使用sed命令替换yml文件中的路径,并尝试注释该文件中的旧路径。注释可以很好地工作,但不是专门针对该路径。该文件中还有其他路径。我的yml文件如下所示: enabled: true close_eof: true #close_inactive: 1h paths: - /home/directory/another_directory/directory_20200910/*_*_* 现在我想让我的文件看起来像 enabled: true clos

我尝试使用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
(酷)的所有行上执行重放,但它将用一个
替换行开头的任何数量的

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

这可能不是你想要的

单引号将阻止变量的扩展
sed-e'/$SPTH/s/^#*/#/“
将在包含文字
$SPTH
的所有行上执行替换(无论是否存在shell变量
SPTH
及其内容是什么)

这可能不是你想要的

如果要展开
$SPTH
,则需要双引号(

(当然,由于
$SPTH
的扩展值包含斜杠,会干扰sed表达式本身,因此会遇到问题)

解决方案 要简单地替换当前目录,请使用以下内容:

SPTH='/home/lt-1027'
sed \
  -e "s|^\( *-  *${SPTH}\)/.*/\*_\*_\*|\1/$(date +%Y%m%d)/*_*_*|" \
  -i test.yml
这将使用管道
|
作为定界字符,以避免
${SPTH}
中的斜杠出现问题。 它将文件的缩进、破折号和开头(直到
${SPTH}
的结尾)捕获到捕获组
\1
,然后在替换中使用该组,因此替换文本具有与原始文本相同的缩进(希望保持yaml完整)

如果要保留原始路径并将其注释掉,请使用

sed\
-e“s^\(\(*-*${SPTH}\)/.*.*.*.*.*.$.\\\.\1\n\2/$(日期+%Y%m%d)/*.*.*。”\
-我测试.yml

这将把整个旧行捕获到引用
\1
(因此,我们可以通过前缀
#
将其替换为注释掉的版本);缩进现在被捕获到
\2

中,使用简单的YAML文本处理工具将无法始终正确工作。如果您知道您的YAML输入将始终具有特定格式,则可以接受这种解决方案

假设您要替换所有出现的

/home/directory/another_directory/directory_<any_number>/*_*_*
使用您的示例输入此打印

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]*\(/\*_\*_\*\)#\1'$(date +%Y%m%d)'\2#' test.yml

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

date +%Y%m%d

POSIX标准未定义此选项
-d
,但在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/*_*_*

使用sed with option-i保存输出

YAML工具需要使用语法感知解析器(如
yq
)进行解析。您可以安装这样的工具吗?-我还没有尝试过安装,我尝试直接使用sed替换它而不使用解析您可以在替换中使用
&
,而不是为整个lin使用额外的捕获组e、 谢谢。我就快到了。你能告诉我,如果我想用同一个脚本将日期更改为昨天吗?这怎么可能?因为我将在创建该日期一天后运行脚本,folderi已经自己完成了。谢谢。我做了
date-d“昨天”+%Y%m%d“昨天=$(date-d“昨天”+%Y%m%d)
date -d yesterday +%Y%m%d
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/*_*_*