基本上我想用以下格式解析日志条目:
a1 b2 c3)@ in#(d4 e5 f6)@ out#(g7 h8 i9
)@in#(
是前两个子字符串(a1 b2 c3
和d4 e5 f6
)之间的第一个定界符。)@out#(
是g7 h8 i9
的可选定界符。有趣的一点是,两个分隔符都包含多个 个字符。
我想使用Bash 正则表达式来获取所有子字符串。这是我当前的代码:
s1='a1 b2 c3 )@in#( d4 e5 f6 )@out#( g7 h8 i9'
s2='a1 b2 c3 )@in#( d4 e5 f6'
regex='^(.*)[[:space:]]+\)@in#\([[:space:]]+(.*)[[:space:]]+\)@out#\([[:space:]](.*)$'
[[ $s =~ $regex ]] && printf '%s\n%s\n%s\n%s\n' "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" "${BASH_REMATCH[3]}
代码仅匹配s1,但不匹配。这就是为什么我写这篇文章来为您提供帮助的原因。
顺便说一句,任何人都可以澄清一下[[:space:]]
和\s
之间的区别。
更新:从下面提供的评论和答案中,也许Bash正则表达式不适用于此处。 awk
会更好。
我不仅要打印输出,还想将它们捕获到变量中或read
捕获到数组中以进行进一步处理。
答案 0 :(得分:0)
您可以尝试Perl
$ echo "a1 b2 c3 )@in#( d4 e5 f6 )@out#( g7 h8 i9" | perl -lne ' @a=split(/\s*\)\@in#\(\s*|\s*\)\@out#\(\s*/); print join("\n",@a) '
a1 b2 c3
d4 e5 f6
g7 h8 i9
$ echo "a1 b2 c3 )@in#( d4 e5 f6 g7 h8 i9" | perl -lne ' @a=split(/\s*\)\@in#\(\s*|\s*\)\@out#\(\s*/); print join("\n",@a) '
a1 b2 c3
d4 e5 f6 g7 h8 i9
$
您可以通过while循环读取输出
$ echo "a1 b2 c3 )@in#( d4 e5 f6 g7 h8 i9" | perl -lne ' @a=split(/\s*\)\@in#\(\s*|\s*\)\@out#\(\s*/); print join("\n",@a) ' | while read x;do; echo "val=$x"; done
val=a1 b2 c3
val=d4 e5 f6 g7 h8 i9
$
或在perl中打印每个arr值,然后一对一读取它们
$ echo "a1 b2 c3 )@in#( d4 e5 f6 g7 h8 i9" | perl -lne ' @a=split(/\s*\)\@in#\(\s*|\s*\)\@out#\(\s*/); print $a[0] ' | read x1
$ echo $x1
a1 b2 c3
$
$ echo "a1 b2 c3 )@in#( d4 e5 f6 g7 h8 i9" | perl -lne ' @a=split(/\s*\)\@in#\(\s*|\s*\)\@out#\(\s*/); print $a[1] ' | read x2
$ echo $x2
d4 e5 f6 g7 h8 i9
$
答案 1 :(得分:0)
我的最终解决方案如下:
IFS=$'\n' _log_array=( $( awk -F'[[:space:]]*\\)@(in|out)#\\([[:space:]]*' '{ print NF; for (i = 1; i <= NF; ++i) print $i; }' <<< $s ) )
IFS
设置为\n
。这里有两个参考文献: