我正在编写一个脚本,用于遍历目录中的一组文件,以在一个文件(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
有点麻烦,我们将添加一些专门针对大括号的额外编码...
当前情况:
$ 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
中有多个匹配的行,您可能会遇到问题>