与可能带有花括号的替换变量一起使用

问题描述 投票:0回答:1

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

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}

outputFile.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'

我已经尝试对有问题的字符串进行硬编码,并尝试使用不同的转义方式来代替curly和引用字符串,但是还没有找到一个成功的组合,而我对如何使其工作一无所知。

编辑我过了很短的时间,忘记了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
bash sed
1个回答
0
投票

有点麻烦,我们将添加一些专门针对大括号的额外编码...

当前情况:

$ 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}

NOTES

  • 如果以set -xv开头编码,则可以看到每个步骤如何解释变量;使用set +xv关闭
  • 显然,如果您实际上在$srcFile中有多个匹配的行,您可能会遇到问题>
  • 如果发现其他需要转义的字符,则需要为所述字符添加其他参数扩展
© www.soinside.com 2019 - 2024. All rights reserved.