Regex Bash中的多行正则表达式匹配

Regex Bash中的多行正则表达式匹配,regex,bash,Regex,Bash,我试图在bash脚本中进行一些相当简单的字符串解析。 基本上,我有一个由多个多行字段组成的文件。每个字段由已知的页眉和页脚包围 我想将每个字段分别提取到一个数组或类似的数组中,如下所示 >FILE=`cat file` >REGEX="@#@#@#[\s\S]+?@#@#@" > >if [[$FILE =~ $REGEX ]] then > echo $BASH_REMATCH >fi 文件: 现在我很确定问题是bash不能将换行符与“.”匹配 我可

我试图在bash脚本中进行一些相当简单的字符串解析。 基本上,我有一个由多个多行字段组成的文件。每个字段由已知的页眉和页脚包围

我想将每个字段分别提取到一个数组或类似的数组中,如下所示

>FILE=`cat file`
>REGEX="@#@#@#[\s\S]+?@#@#@"
> 
>if [[$FILE =~ $REGEX ]] then
>   echo $BASH_REMATCH
>fi
文件:

现在我很确定问题是bash不能将换行符与“.”匹配

我可以将其与“pcregrep-M”匹配,但当然整个文件都将匹配。我能从pcregrep一次得到一场比赛吗


我并不反对使用一些内联perl或类似的工具。

我会围绕
awk
构建一些东西。以下是第一个概念证明:

awk '
    BEGIN{ f=0; fi="" }
    /^@#@#@#################################$/{ f=1 }
    /^@#@#@#$/{ f=0; print"Field:"fi; fi="" }
    { if(f==2)fi=fi"-"$0; if(f==1)f++ }
' file
begin=“#########################
end=“@#@#@#”
i=0
标志=0
而read-r行
做
案例$line in
$begin)
flag=1;;
$end)
((i++)
flag=0;;
*)
如果[$flag==1]]
然后
数组[i]+=“$line”$'\n'#保留换行符
fi;;
以撒
完成<数据文件
如果要在数组元素中保留标记行,请将赋值语句(及其标志测试)移动到
的顶部,同时将
循环移动到
案例之前的

(如果您有gawk)

awk 'BEGIN{ RS="@#*#" }
NF{
    gsub("\n"," ") #remove this is you want to retain new lines
    print "-->"$0 
    # put to array
    arr[++d]=$0
} ' file
输出

$ ./shell.sh
--> this is field one
--> this is field two they can be any number of lines
该语言执行整个文档的多行匹配,绑定变量,并(使用
-B
“dump bindings”选项)发出正确转义的shell变量赋值,这些赋值可以
求值
-ed。支持数组

@
字符是特殊的,因此必须将其对折以匹配字面意思

$ cat fields.txr
@(collect)
@@#@@#@@#################################
@  (collect)
@field
@  (until)
@@#@@#@@#
@  (end)
@  (cat field)@# <- catenate the fields together with a space separator by default
@(end)

$ txr -B fields.txr data
field[0]="this is field one"
field[1]="this is field two they can be any number of lines"

$ eval $(txr -B fields.txr data)
$ echo ${field[0]}
this is field one
$ echo ${field[1]}
this is field two they can be any number of lines
$cat fields.txr
@(收款)
@@#@@#@@#################################
@(收款)
@场
@(直至)
@@#@@#@@#
@(完)

@(猫场)#稍微修改了一下以满足我的需要。Awk是我从未学过的东西。谢谢
$ ./shell.sh
--> this is field one
--> this is field two they can be any number of lines
$ cat fields.txr
@(collect)
@@#@@#@@#################################
@  (collect)
@field
@  (until)
@@#@@#@@#
@  (end)
@  (cat field)@# <- catenate the fields together with a space separator by default
@(end)

$ txr -B fields.txr data
field[0]="this is field one"
field[1]="this is field two they can be any number of lines"

$ eval $(txr -B fields.txr data)
$ echo ${field[0]}
this is field one
$ echo ${field[1]}
this is field two they can be any number of lines