grep - 正则表达式 - 匹配到特定单词

时间:2013-12-04 10:50:45

标签: regex bash grep

假设我有一个像这样的行的文件

abcefghijklxyz
abcefghijkl

我想只获取abc和行尾之间的字符串。行尾可以定义为正常的行尾或字符串xyz

我的问题是

如何使用grep和正则表达式仅获取匹配的字符串?例如,上面显示的两条线的预期输出将是

efghijkl
efghijkl

我不想要开始和结束标记。

到目前为止我一直在尝试

grep -oh "abc.*xyz"

我使用Ubuntu 13.04和Bash shell。

4 个答案:

答案 0 :(得分:6)

此行会排除前导abc结尾 xyz(如果有),并为您提供所需的部分:

grep -oP '^abc\K.*?(?=xyz$|$)'

以你的例子:

kent$  echo "abcefghijklxyz
abcefghijkl"|grep -oP '^abc\K.*?(?=xyz$|$)'
efghijkl
efghijkl

在文本中间加xyz的另一个例子:

kent$  echo "abcefghijklxyz
abcefghijkl
abcfffffxyzbbbxyz
abcffffxyzbbb"|grep -oP '^abc\K.*?(?=xyz$|$)'
efghijkl
efghijkl
fffffxyzbbb
ffffxyzbbb

答案 1 :(得分:2)

使用sed:

sed -n '/abc/{s/.*abc\(.*\)/\1/;s/xyz.*//;p}' input

产地:

efghijkl
efghijkl

答案 2 :(得分:1)

像这样使用look-behind

$ grep -Po '(?<=abc)[^x]*' file
efghijkl
efghijkl

它会在abc之后获取所有内容,直到找到x


基于Kent's answer(不是要复制,但为了完整性),您可以在grepabc(或行尾)内xyz完成所有内容:

$ grep -Po '(?<=abc).*(?=xyz|$)' file
efghijklxyz
efghijkl

答案 3 :(得分:0)

或者你可以删除你不喜欢的东西:

awk '/^abc/{sub(/^abc/,x);sub(/xyz.*$/,x)}1' file
efghijkl
efghijkl

xyz.*$代表从xyz到行尾的所有内容。