Sed 发现并替换两种模式之间的文本

Sed 发现并替换两种模式之间的文本

亲爱的 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由于左大括号和右大括号不匹配,原件格式错误

相关内容