Извлечь первое совпадение в строке с помощью sed

Извлечь первое совпадение в строке с помощью sed

У меня образовалась серия линий.

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

Каждая строка имеет идентификатор шаблона (sed) [A-Za-z]\+-[0-9]\+, т. е. один или несколько алфавитов, за которыми следует тире (-), за которым следует одна или несколько цифр. Они встречаются в любом месте строки.

Мне нужно извлечь идентификаторы. Я думал прикрепить 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— это добавить маркеры вокруг идентификатора в одной команде и извлечь с помощью другой, как показано ниже.

Есть ли лучший способ сделать это в 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перед каждым совпадением символ, который не является частью совпадения, а затем удалите все до последнего 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

Связанный контент