使用 sed 提取第一个匹配项

使用 sed 提取第一个匹配项

我有一系列的线条形式。

Agenda HR-1 Presented by XYZ
HR-2 Debate-1 - All
HR-3 Debate-2 - All
(Cov-4) Conclusion 

每一行都有一个 (sed) 模式的 ID [A-Za-z]\+-[0-9]\+,即一个或多个字母后跟一个破折号 (-),后跟一个或多个数字。它们出现在队列中的任何位置。

我需要提取 ID。我的想法是.*在开头和结尾粘贴 a并打印\1,但我无法让它工作。

回复说 sed 仅替换第一个匹配项,这是正确的:

$ cat /tmp/scratch/x | sed -n   's/\<\([A-Za-z]\+-[0-9]\+\)/ID:\1/p'
Agenda ID:HR-1 Presented by XYZ
ID:HR-2 Debate-1 - All
ID:HR-3 Debate-2 - All
(ID:Cov-4) Conclusion

但当然,.*开始时会贪婪地转到最后一场比赛:

$ cat /tmp/scratch/x | sed -n   's/.*\<\([A-Za-z]\+-[0-9]\+\).*/ID:\1/p'
ID:HR-1
ID:Debate-1
ID:Debate-2
ID:Cov-4

我能想到的唯一方法sed是在一个命令中的 ID 周围添加标记,然后使用另一个命令进行提取,如下所示。

在 sed 中是否有更好的方法来做到这一点?

$ cat x | sed -n   's/\<\([A-Za-z]\+-[0-9]\+\)/<id>\1<~id>/;s/.*<id>\(.*\)<~id>.*/\1/;p'
HR-1
HR-2
HR-3
Cov-4

答案1

使用 GNU awk,尝试:

gawk -v FPAT='[A-Za-z]+-[0-9]+' '$1{print $1}' FILE

或者:

gawk -v FPAT='[A-Za-z]+-[0-9]+' '$0=$1' FILE

答案2

sed,尝试:

<FILE sed -En '/([[:alpha:]]+-[0-9]+).*/{ s//:\1/; s/.*://p; }'
  • 删除所需匹配项后的所有内容
  • 现在匹配位于每一行的末尾——这可以通过多种方式处理
    • 上面的内容很容易阅读 -char在每场比赛之前放置不属于比赛一部分的 a ,然后char使用第二个s命令删除直到最后一个的所有内容
    • 第二个s命令的另一个选项是删除不属于匹配部分的字符之前的所有内容:
<FILE sed -En '/([[:alpha:]]+-[0-9]+).*/{ s//\1/; s/.*[^[:alnum:]-]//; p; }'

答案3

我们Perl可以这样做:

$ perl -lne 'print /([a-z]+-\d+)/i' file

输出

HR-1
HR-2
HR-3
Cov-4

相关内容