我正在尝试在bash脚本中进行一些相当简单的字符串解析。 基本上,我有一个由多个多行字段组成的文件。每个字段都由一个已知的页眉和页脚包围。
我想将每个字段分别提取到数组或类似字符中,如此
>FILE=`cat file`
>REGEX="@#@#@#[\s\S]+?@#@#@"
>
>if [[$FILE =~ $REGEX ]] then
> echo $BASH_REMATCH
>fi
文件:
@#@#@#################################
this is field one
@#@#@#
@#@#@#################################
this is field two
they can be any number of lines
@#@#@#
现在我很确定问题是bash与“。”
的新行不匹配我可以将它与“pcregrep -M”匹配,但当然整个文件将匹配。我可以一次从pcregrep获得一场比赛吗?
我并不反对使用某些内联perl或类似内容。
提前致谢
答案 0 :(得分:3)
如果你有傻瓜
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
答案 1 :(得分:1)
TXR语言执行全文档多行匹配,绑定变量,以及(使用-B
“dump bindings”选项)发出适当的转义shell变量赋值,可以是{{1} } -ed。支持数组。
eval
字符是特殊的,所以它必须加倍才能字面匹配。
@
$ 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
语法匹配整行。这些被收集到列表中,因为它位于@field
内,并且列表被收集到列表列表中,因为它嵌套在另一个@(collect)
中。然而,内部@(collect)
将内部列表减少为单个字符串,因此我们最终得到一个字符串列表。
这是“经典TXR”:它最初是如何设计和使用的,是由这个想法引发的:
为什么我们不在这里 - 文件向后工作并从大量文本解析为变量?
默认情况下,默认情况下,在shell语法中,默认情况下,匹配变量的隐式发送仍然是受支持的行为,即使语言变得更加强大,因此不需要与shell脚本集成。
答案 2 :(得分:0)
我会围绕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
答案 3 :(得分:0)
begin="@#@#@#################################"
end="@#@#@#"
i=0
flag=0
while read -r line
do
case $line in
$begin)
flag=1;;
$end)
((i++))
flag=0;;
*)
if [[ $flag == 1 ]]
then
array[i]+="$line"$'\n' # retain the newline
fi;;
esac
done < datafile
如果要将标记线保留在数组元素中,请将赋值语句(带有标记测试)移到while
之前case
循环的顶部。