Bash 将sed与可能有花括号的替换变量一起使用
我正在编写一个脚本,用于在目录中的一组文件上循环搜索一个文件srcFile中的字符串stringA,复制它后面的行stringToCopy,并将它粘贴到另一个文件outputFile中另一个搜索字符串stringB之后的行上。到目前为止,我拥有的复制/粘贴脚本如下Bash 将sed与可能有花括号的替换变量一起使用,bash,sed,Bash,Sed,我正在编写一个脚本,用于在目录中的一组文件上循环搜索一个文件srcFile中的字符串stringA,复制它后面的行stringToCopy,并将它粘贴到另一个文件outputFile中另一个搜索字符串stringB之后的行上。到目前为止,我拥有的复制/粘贴脚本如下 stringA="This is string A" stringB="This is string B" srcFile=srcFile.txt outpuFile=outputFile.txt replacement="/$str
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
但塞德却被他的话噎住了
sed: -e expression #1, char 106: unknown command: `m'
我尝试过对有问题的字符串进行硬编码,并尝试了不同的变体,例如避开卷曲和引用字符串,但没有找到一个成功的组合,我对如何使其工作感到困惑
编辑
我有一个derp时刻,忘记了我的stringA也有花括号,这碰巧导致我的awk命令计算多行。这导致我的stringToCopy中出现了新行,这是我真正的问题,而不是花括号。所以真正的问题是,如何让awk将大括号视为文字字符,以便
srcFile.txt
stringA=这是字符串A:{0}
不将stringToCopy设置为
有点混乱,我们将添加一些专门用于大括号的额外编码 当前情况:
$ 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中有多个匹配行,您可能会遇到问题
如果发现需要转义的其他字符,则需要为所述字符添加额外的参数扩展
工作方法是将变量的内容写入临时文件,并使用rsed命令。
$ 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 -i "/$stringB/b;n;c${stringToCopy}" $outputFile
$ cat "${outputFile}"
This is string B
text to copy: {0}