我正在尝试从格式有些特殊的字符串中提取几个数据字段。
每个字符串的格式类似于以下内容(添加空格以强调):
1 abcd 2 1 efg 2 hij 3 klmnopqrs 5 tuv 6 5 wxyzäüö 6
其中每个数字代表另一个字段分隔符。这就是我试图提取的内容:
abcd hij klmnopqrs 5 tuv 6 wxyz
在某些情况下,1..2
和模式仅出现一次。范围仅出现在 之前。范围仅出现在.5..6
1..2
3
5..6
3
到目前为止,我已经成功提取abcd
并hij
使用以下代码:
abcd
:echo "$STRING" | awk 'BEGIN{ RS="2"}{gsub(/.*1/,"");print;exit}'
hij
:echo "$STRING" | awk 'BEGIN{ RS="3"}{gsub(/.*2/,"");print;exit}'
现在我正在寻找一种方法来抓取wxyz
和klmnopqrs
。
wxyz
是前四中的字符最后的5..6
字符串的范围模式klmnopqrs
是由第一的的发生3
和最后的的发生5
在网上搜索了一个小时后,我现在束手无策。如果您能找到提取这些范围模式的方法,我将不胜感激。
编辑:以下是一些更接近真实情况的输入示例:
(test)(te st) tesst. test test test test [teest] [teseeet]
(teeeest)(te st) tst. tet test [teseet]
(tst) tst. tet test [tseeet]
这就是我想在每种情况下提取的内容:
test tesst test test test test [teest] tese
teeeest tst tet test tese
tst tst tet test tsee
如您所见,字段分隔符是特殊字符。字符串的宽度以及1..2
和5..6
范围的数量(此处(..)
和[..]
)都是可变的。
答案1
echo "1 abcd 2 1 efg 2 hij 3 klmnopqrs 5 tuv 6 5 wxyzäüö 6" |
perl -lne '
@out = ();
/1 (.+?) 2/ and push @out, $1;
/.+2 \K(.+?) 3 (.+?)(?= 5)/ and push @out, $1, $2;
/(5.+?6)/ and push @out, $1;
/.+5 (....)/ and push @out, $1;
print join " ", @out
'
abcd hij klmnopqrs 5 tuv 6 wxyz
我们需要注意正确转义正则表达式特殊字符:
perl -lne '
@out = ();
/\((.+?)\)/ and push @out, $1;
/.+\) \K(.+?)\.(.+)(?= \[)/ and push @out, $1, $2;
/.+\[(....)/ and push @out, $1;
print join " ", @out
' <<END
(test)(te st) tesst. test test test test [teest] [teseeet]
(teeeest)(te st) tst. tet test [teseet]
(tst) tst. tet test [tseeet]
END
test tesst test test test test [teest] tese
teeeest tst tet test tese
tst tst tet test tsee
您想要的输出:
test tesst test test test test [teest] tese
teeeest tst tet test tese
tst tst tet test tsee