亲爱的 Stack Exchange 社区,
我看到了其他解决方案,但我正在努力解决正则表达式问题,我需要使它们适应我的情况。
我有软件生成的文件,其中包含 lib 对象成员属性以及需要替换的名称。我需要使用 sed 查找属性的任何名称,并将其替换为基本文件名。
从名为 bobby.js 的 .js 文件开始,其中包含:
// stage content:
(lib.Scenario2IntroFigure0 = function(mode,startPosition,loop) {
stuff
}
以相同的 bobby.js 文件结尾,但现在有:
// stage content:
(lib.bobby = function(mode,startPosition,loop) {
stuff
}
注意:场景2介绍图0是不同的不幸的是,对于每个文件。
描述我认为我应该做什么的伪代码:
A. 通过查找此模式之间的任何内容来隔离旧名称::
// stage content:
(lib.
B. 这个结尾模式:
= function(mode,startPosition,loop) {
C. 使用以下命令获取文件基本名称本身:
FILENAME=$(basename $1 '.js')
D. 用文件基本名称替换旧名称并覆盖文件,如下所示:
sed -i "s/Scenario2IntroFigure0/$DA_FILE/g" $1
但是其中“Scenario2IntroFigure0”是 sed 在这两种模式之间找到的任何内容。
答案1
替换$file
为您的$1
:
file="bobby.js"
filename=$(basename "$file" '.js')
sed -i 's/\((lib\.\).*\( = function(mode,startPosition,loop) {\)/\1'"$filename"'\2/' "$file"
答案2
使用 GNU awk 执行 gensub():
$ awk -v RS= '{ $0=gensub(/(.*\/\/\s+stage content:\s+\(lib\.)\S+(\s+=\s+function\(mode,startPosition,loop\)\s+\{.*)/,"\\1" gensub(/\.js$/,"",1,FILENAME) "\\2",1) } 1' bobby.js
// stage content:
(lib.bobby = function(mode,startPosition,loop) {
stuff
}
awk -i inplace -v RS=...
如果您想要“就地”编辑,请进行此操作。
答案3
从 @Freddy 开始,但包括 OP 要求比赛是跨线的。通过替换\n
为来完成NULL
使用sed
tr '\n' '\0'
然后在 后将它们切换回来sed
。
f="bobby.js"
b=$(basename "$f" '.js')
pre="// stage content:\x00\(lib." #pattern includes NULL (\x00)
post=" = function\(mode,startPosition,loop\)"
cat $f | tr '\n' '\0' | sed -E "s|($pre)[[:alnum:]]+($post)|\1$b\2|g" | tr '\0' '\n'
编辑
一个纯粹的sed
解决方案,不涉及任何混乱tr
f="bobby.js"
b=$(basename "$f" '.js')
pre="\/\/ stage content:"
mid="\(lib."
post=" = function\(mode,startPosition,loop\)"
sed -E "/^$pre$/{$!{ N;s|($pre\n$mid)[[:alnum:]]+($post)|\1$b\2|;ty;P;D;:y}}" $f
该解决方案得益于对这个帖子和这个。我希望读完它们后你的大脑不会像我一样疼痛,但我在这个过程中学到了很多东西。尊重海报,包括@Peter.O
我们不值得!
后脚本
bobby.js
由于左大括号和右大括号不匹配,原件格式错误