使用 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

相關內容