【问题标题】:Using sed with a substitution variable that may have curly braces将 sed 与可能带有花括号的替换变量一起使用
【发布时间】:2020-05-27 22:22:50
【问题描述】:

我正在编写一个脚本,用于遍历目录中的一组文件,在一个文件 (srcFile) 中搜索字符串 (stringA),复制其后面的行 (stringToCopy),然后将其粘贴到另一个文件 (outputFile) 中的另一个搜索字符串 (stringB) 之后的行上。我目前的复制/粘贴脚本如下

stringA="This is string A"
stringB="This is string B"
srcFile=srcFile.txt
outpuFile=outputFile.txt
replacement="/$stringA/{getline; print}"
stringToCopy="$(awk "$replacement" $srcFile)"
sed -i "/$stringB/!b;n;c${stringToCopy}" $outputFile

脚本运行良好,除非stringToCopy 最终包含花括号。例子是

srcFile.txt:

This is string A
text to copy: {0}

输出文件.txt:

This is string B
line to be replaced

脚本完成后,我希望outputFile.txt

This is string B
text to copy: {0}

但是 sed 被

sed: -e expression #1, char 106: unknown command: `m'

我尝试对有问题的字符串进行硬编码,并尝试转义花括号和引用字符串的不同变体,但没有找到成功的组合,我不知道如何使它工作。

编辑 我有一个糟糕的时刻,忘记了我的stringA 也有花括号,这恰好导致我的 awk 命令对多行进行数学运算。这导致我的stringToCopy 中有换行符,这是我真正的问题,而不是花括号。所以真正的问题是,如何让 awk 将花括号视为文字字符,以便 srcFile.txt

This is string A: {0}
text to copy: {0}

This is string A:
Other junk

还有stringA="This is string A: {0}"

未将stringToCopy 设置为

text to copy: {0}
Other junk

【问题讨论】:

  • 工作方式是将变量内容写入临时文件,使用rsed命令。

标签: bash sed


【解决方案1】:

有点麻烦,因为我们要为大括号添加一些额外的编码......

目前情况:

$ awk '/This is string A: {0}/{getline; print}' srcFile.txt
text to copy: {0}                   # this is the line we want
Other junk                          # we do not want this line

我们可以通过转义搜索模式中的大括号来消除第二行,例如:

$ awk '/This is string A: \{0\}/{getline; print}' srcFile.txt
text to copy: {0}

那么,如何摆脱大括号呢?我们可以使用一些显式的参数扩展来将 $stringA 变量中的大括号替换为转义大括号,请记住,我们还需要在参数扩展阶段对大括号进行转义:

$ stringA="This is string A: {0}"
$ stringA="${stringA//\{/\\{}"      # replace '{' with '\{'
$ stringA="${stringA//\}/\\}}"      # replace '}' with '\}'
$ echo "${stringA}"
This is string A: \{0\}

然后我们可以继续执行其余代码:

$ replacement="/$stringA/{getline; print}"
$ echo "${replacement}"
/This is string A: \{0\}/{getline; print}

$ stringToCopy="$(awk "$replacement" $srcFile)"
$ echo "${stringToCopy}"
text to copy: {0}

至于最后的sed 步骤,我必须删除! 才能使其正常工作:

$ sed -i "/$stringB/b;n;c${stringToCopy}" $outputFile
$ cat "${outputFile}"
This is string B
text to copy: {0}

注意事项

  • 如果您在编码前加上set -xv,您可以看到变量在每个步骤中是如何被解释的;使用set +xv 关闭
  • 很明显,如果您确实在$srcFile 中有超过 1 个匹配行,您可能会遇到问题
  • 如果您发现需要转义的其他字符,则需要为这些字符添加额外的参数扩展

【讨论】:

    猜你喜欢
    • 2016-11-25
    • 2014-03-09
    • 1970-01-01
    • 2013-01-26
    • 2018-03-21
    • 1970-01-01
    • 1970-01-01
    • 2012-08-25
    • 1970-01-01
    相关资源
    最近更新 更多