Regex 换行后SED脚本与多行模式中的单行不匹配
我正在尝试生成一个sed脚本来转换Regex 换行后SED脚本与多行模式中的单行不匹配,regex,bash,sed,Regex,Bash,Sed,我正在尝试生成一个sed脚本来转换 &&a_x* &&b_x;cx &&d_x* 进入 A*应触发已删除的A的复制一个简单的换行符 我有一个SED脚本,它首先插入换行符(包括使用;的操作),然后在不使用的情况下执行复制的多行模式 如果我将多行模式移动到一个单独的脚本文件中,并通过管道输出用于执行换行符的指令,那么多行模式就可以工作 出于某种奇怪的原因,一个脚本文件是不行的——出于维护的原因,这正是我想要的 以下是组合版本: #!/bin/sed
&&a_x* &&b_x;cx &&d_x*
进入
A*
应触发已删除的A的复制代码>一个简单的换行符
我有一个SED脚本,它首先插入换行符(包括使用;
的操作),然后在不使用的情况下执行复制的多行模式
如果我将多行模式移动到一个单独的脚本文件中,并通过管道输出用于执行换行符的指令,那么多行模式就可以工作
出于某种奇怪的原因,一个脚本文件是不行的——出于维护的原因,这正是我想要的
以下是组合版本:
#!/bin/sed -f
# Remove whitespaces
s/\ //g
# Linebreak on &&
s/\&\&/\
\&\&/g
### Linebreak on ;
s/\;/\
/g
# Remove extra new line
s/\n//
:extendvars
/^..*\*$/ {
l //DEBUG SWITCH
h
s/\(\&\|\*\)\(\&\|\*\)*//g
p
g
s/\(\&\|_\|-\|\*\)\(\&\|_\|-\|\*\)*//g
p
d
bextendvars;
}
&&a_x*\n&&b_x\nbx\n&&c_x*$
a_x
b_x
bx
c_x
ax
bx
bx
cx
&&a_x*$
a_x
ax
&&b_x
bx
&&c_x*$
c_x
cx
多行模式第一行中的调试开关“l”应仅匹配以*结尾的行,但匹配所有行和输出
&&a_x*\n&&b_x\bx\n&&c_x*$
在有故障的组合版本中。对其进行配管时,sed正确识别模式:
&&a_x*$ ... &&c_x*$
输出错误(组合版本):
正确的输出(管道版本):
我用计算机运行脚本
sed -f [SCRIPTNAME] <old >new
sed-f[SCRIPTNAME]新建
在这个版本中,我已经从&&b_x
jet中删除了&&
即使在一个脚本中执行所有语句,如何让SED识别正确的模式?
为什么SED突然无法匹配以*
结尾的单行
谢谢你的帮助 代码不再循环的原因实际上与循环条件无关;就是在圈内,你跑
d
…这将中止当前输入行的处理。您从输入行在模式空间中构造了几行是不重要的d
告诉sed停止它正在做的事情,读取下一行输入(如果有),然后重新开始
不管怎样,我觉得你的方法太复杂了。我建议(用GNU的说法,因为机制在GNU代码中更为明显)
您似乎花了很大的精力使代码在非GNU-sed的情况下工作,因此这里有一个POSIX版本,它也做了同样的事情:
#!/bin/sed -f
s/[[:space:]]*&&[[:space:]]*/\
/g
s/[[:space:]]*;[[:space:]]*/\
/g
s/^/\
/
s/\(\n[^\n]\)_x\*/\1_x\1x/g
s/^\
*//
这将删除标记周围的空白。这似乎是一件明智的事情。如果您不希望发生这种情况,那么必须从代码中删除与空格匹配的部分,并且必须为标记行末尾的空格做出规定
#!/bin/sed -rf
s/^|&&|;/\n/g
s/(\n[^\n])_x\*([[:blank:]]*)/\1_x\1x\2/g
s/^\n//
是GNU sed代码的一种可能的改编。一个简单的awk可以比这里的sed更具可读性。尝试此awk
命令:
s='&&a_x* &&b_x;cx &&d_x*'
echo "$s" | awk -F '\\*' -v RS='&&|;' 'NF{s=$1;print s} NF==2{sub(/_/, "", s);print s}'
a_x
ax
b_x
cx
d_x
dx
哦,我喜欢。闪亮的值得注意的是,并非所有AWK都支持正则表达式(甚至多字符)RS
,因此鉴于OP在sed代码中努力避免Gnuism,我不确定这对他是否有效,但这对大多数人来说是一种很好的方式。是的,我应该提到它确实是gnu awkYeah,很酷的替代解决方案-我将把AWK放在我的下一个列表中!
#!/bin/sed -rf
s/^|&&|;/\n/g
s/(\n[^\n])_x\*([[:blank:]]*)/\1_x\1x\2/g
s/^\n//
s='&&a_x* &&b_x;cx &&d_x*'
echo "$s" | awk -F '\\*' -v RS='&&|;' 'NF{s=$1;print s} NF==2{sub(/_/, "", s);print s}'
a_x
ax
b_x
cx
d_x
dx