在 shell 脚本上选择模式前后的单词(连字符是模式)

Raj*_*Raj 5 shell awk sed

使用 shell 脚本在模式之前和之后选择一个单词(连字符是模式)。

Out 是一个有数百行的文本文件,我选择了具有必需 ID 的那些,但是我需要选择 ALPHABETS-NUMBERS。字母和数字的计数各不相同。

我尝试了各种实用程序,包括 cut、sed、awk,但是它正在修剪所需的字段。

输入

cat out | grep "[A-Z][-][0-9]"
BUG-KEYWORD-BUG-101
ABC-10
DEF-10327
Output is referred in ABC-1043
Please refer DEF-11234
Run Code Online (Sandbox Code Playgroud)

输出应该是

BUG-101
ABC-10
DEF-10327
ABC-1043
DEF-11234
Run Code Online (Sandbox Code Playgroud)

Wik*_*żew 1

您可以使用

grep -oE '[[:alpha:]]+-[0-9]+' file
Run Code Online (Sandbox Code Playgroud)

o选项grep仅使输出匹配,E启用 POSIX ERE 语法(无需转义+),并[[:alpha:]]+-[0-9]+匹配以一个或多个字母开头、然后有一个-字符、然后有一个或多个数字的所有子字符串。

备择方案

上述解决方案提取所有多个匹配项,即使它们出现在文件中的同一行。如果您不希望出现这种行为,而只想匹配行<letters>-<digits> 尾的,则只需$在正则表达式模式的末尾添加并使用

grep -oE '[[:alpha:]]+-[0-9]+$' file`
Run Code Online (Sandbox Code Playgroud)

如果您需要提取每行上不一定位于行尾的最后一个匹配项,请使用带有 GNU 的基于 PCRE 的正则表达式,grep或者pcregrep(如果您安装了它,则使用非 GNUgrep版本的常见解决方法工具):

grep -oP '^(?:.*\P{L})?\K\p{L}+-\d+' file
pcregrep -o '^(?:.*\P{L})?\K\p{L}+-\d+' file
Run Code Online (Sandbox Code Playgroud)

请参阅此正则表达式演示。在 PCRE 模式中,\p{L}匹配任何字母(您也可以仍然使用[[:alpha:]])并\d匹配任何 ASCII 数字,^(?:.*\P{L})?\K匹配字符串的开头 ( ^),然后匹配除换行符之外的任何零个或多个字符的可选序列,尽可能多( .*) ,然后是字母 ( \P{L}) 以外的任何字符,这部分使引擎转到最后一次匹配出现的位置\p{L}+-\d+

主要解决方案请参见在线演示

s='BUG-KEYWORD-BUG-101
ABC-10
DEF-10327
Output is referred in ABC-1043
Please refer DEF-11234'
grep -oE '[[:alpha:]]+-[0-9]+' <<< "$s"
Run Code Online (Sandbox Code Playgroud)

输出:

BUG-101
ABC-10
DEF-10327
ABC-1043
DEF-11234
Run Code Online (Sandbox Code Playgroud)