【问题标题】:Replace block with variable containing multiple lines containing special characters用包含多行包含特殊字符的变量替换块
【发布时间】:2019-11-22 19:33:29
【问题描述】:

我有一个文件 out.txt

test1 {
       car "ok"
       disk "N/A"
       tire 4
}

我需要用另一个应该在变量(bash)中的块替换整个块/test1 {/ , /\}/

所以在脚本中是这样的:

#!/bin/bash
var="
    test1 {
           car "fail"
           disk "2"
           tire 1
    }
"
sed -r --follow-symlinks -e "/^test1 /,/\}/c\\${text}" out.conf

由于 sed 使用 { 和新行(如其 sed 参数)处理变量,这当然不起作用......但是如何绕过它?

【问题讨论】:

  • 您使用几乎有效的JSON有什么原因吗?切换到标准格式可能更有意义。
  • @tripleee 哦,伙计,如果我可以使用有效的 Json,这将使我的生活 100% 更轻松,可悲的是,正如你所说的“几乎有效”的 json .. 所以我必须想出这么多有线的东西使事情自动化,甚至都不好笑。这只是一个小例子,接近我必须使它更容易解决的问题。而且我无法更改格式:-/
  • @VladoPortos:您想要一个仅 sed 的解决方案还是使用更适合的工具(如 awk/perl)?
  • @anubhava 最好是 sed,但据我所知,没有简单的解决方案,所以如果 awk 可以让它变得简单,我会使用它:)
  • 您的替换块能否在双引号字符串或其他任何地方包含}\t(或其他转义字符)?输入文件中的test1 {} 定界符是否总是在自己的行上?

标签: linux bash awk sed


【解决方案1】:

sed 相比,使用awk 更容易执行此操作,因为多行替换和替换文本。你可以使用这个awk:

var="
    test1 {
           car "fail"
           disk "2"
           tire 1
    }
"
awk -v var="$var" 'p && /^[[:blank:]]*}[[:blank:]]*$/ { $0=var; p=0 } 
/^[[:blank:]]*test1[[:blank:]]*\{/ { p=1 } !p' out.conf

这个 awk 的工作原理如下:

  • 在一行中搜索文本test1 { 并设置标志p=1
  • p==1 不打印任何内容时继续读取文件
  • 如果p==1 并找到带有} 的行,则设置$0 并在变量var 中传递多行文本并重置p=0
  • 仅在p==0 时打印行

【讨论】:

  • thanks 像魅力一样工作,不是原始问题中所要求的 sed,但 sed 解决方案要复杂得多。我接受这个作为答案。
  • 很高兴它成功了。您可以从您的问题标题中删除 sed :)
  • 欢迎来到我的世界 :D 哈哈哈我知道这很痛苦
  • @VladoPortos 您可以随时提出后续问题。根据您无法在评论中完全提供但可以在问题中提供的详细信息,这可能没有您想象的那么困难。
  • 谢谢@EdMorton,我想我已经解决了,有点落后的解决方案,但似乎工作......我现在正在测试它:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-30
  • 2018-09-11
  • 1970-01-01
  • 2019-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多