Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 换行后SED脚本与多行模式中的单行不匹配_Regex_Bash_Sed - Fatal编程技术网

Regex 换行后SED脚本与多行模式中的单行不匹配

Regex 换行后SED脚本与多行模式中的单行不匹配,regex,bash,sed,Regex,Bash,Sed,我正在尝试生成一个sed脚本来转换 &&a_x* &&b_x;cx &&d_x* 进入 A*应触发已删除的A的复制一个简单的换行符 我有一个SED脚本,它首先插入换行符(包括使用;的操作),然后在不使用的情况下执行复制的多行模式 如果我将多行模式移动到一个单独的脚本文件中,并通过管道输出用于执行换行符的指令,那么多行模式就可以工作 出于某种奇怪的原因,一个脚本文件是不行的——出于维护的原因,这正是我想要的 以下是组合版本: #!/bin/sed

我正在尝试生成一个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