【问题标题】:sed replacing string in quotes; with backreferences; shell scriptsed 替换引号中的字符串;带有反向引用;外壳脚本
【发布时间】:2021-08-13 17:10:10
【问题描述】:

我在这方面工作太久了,所以我怀疑我错过了一些基本的东西。

很抱歉,这可能是有据可查的,但我已阅读,但我仍然没有得到它。

我正在尝试替换一行中的日期。原行如下:

date = "2020-11-01"

我试图用今天的日期替换那个日期,所以我有:

text_date="$(date +%Y\-%m\-%d)"
sed -i 's/(date = ")*(")/\1'"$text_date"'\2/g' "$post_dir"/index.md

我尝试转义空格和引号(以及等号),但我感到很沮丧。

我目前遇到一个错误:

sed: -e expression #1, char 33: invalid reference \1 on `s' command's RHS

对可能发生的事情有任何想法吗?非常感谢!

【问题讨论】:

    标签: shell sed zsh


    【解决方案1】:

    您的原始帖子离您不远了。使其在我的系统上运行的更改:

    • 为捕获组转义括号:( -> \(, ) -> \)
    • 使通配符在正则表达式中起作用:* -> .*
    • 添加了显式就地扩展:-i -> -i ''

    结果:

    text_date="$(date +%Y\-%m\-%d)"
    sed -i '' 's/\(date = "\).*\("\)/\1'"$text_date"'\2/g' "$post_dir"/index.md
    

    您可能希望使替换模式更明确,以避免更改文件中任何相似但不完全匹配的行。此版本添加了对日期中数字的检查,并使用^$ 确保模式是一行中唯一的内容:

    sed -i '' \
        's/^\(date = "\)[12][0-9][0-9][0-9]-[01][0-9]-[0-3][0-9]"$/\1'$(date +%Y-%m-%d)'"' \
        "$post_dir"/index.md
    

    这不使用-r,因为macOS 上sed 的默认版本不支持它。正如其他答案所指出的那样,这可以使命令更简洁。

    【讨论】:

      【解决方案2】:

      在 bash 中,引号的作用更像是控制字符扩展的开关 shell 比字符串的开头和结尾(有关详细说明,请参阅this great site)。因此你可以'关闭 单引号(防止扩展),放置新数据,然后 'turn 单引号回到':

      sed 's/\(date = \).*/\1"'$(date +%Y\-%m\-%d)'"/' your_file
      

      一旦你确认这是你想要的,你可以添加-i来做 就地替换:

      sed -i 's/\(date = \).*/\1"'$(date +%Y\-%m\-%d)'"/' your_file
      

      【讨论】:

      • 您也可以使用-r--regexp-extended 开关来使用\(date = "\) 等捕获组,而无需转义括号。
      • 感谢这些提示! (我还在学习 sed,所以我会按照你的建议去玩)
      • 在我的系统上(macOS,它有一个古老的 sed 版本),-i 需要一个明确的参数:sed -i '' 'cmd' ...(删除并重新添加了我的评论;前一个有错误) .
      【解决方案3】:

      Bash 扩展需要双引号而不是单引号。问题是文本中有双引号,因此需要转义:

      sed -rn "s/(^date = \")(.*)(\".*$)/\1$(date +%Y\-%m\-%d)\3/p" <<< 'date = "2020-11-01"'
      

      使用 -r 允许正则表达式解释,然后使用括号将文本分成三个部分。将文本替换为第一部分,日期命令的扩展然后是第三部分。

      【讨论】:

      • 非常感谢!几个问题...为什么我需要捕获原始日期?为什么我需要.** 会抓住一切,对吧? &lt;&lt;&lt; 和之后的东西的目的是什么?无论文件中的原始日期是什么,我都希望它能够工作。再次感谢您!
      • 如果解决方案符合您的要求,请花时间对解决方案进行投票并接受它作为答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-11
      • 2020-03-27
      • 2022-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多