У меня образовалась серия линий.
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