Extraia a primeira correspondência de acordo com sed

Extraia a primeira correspondência de acordo com sed

Eu tenho uma série de linhas formadas.

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

Cada linha possui um ID do padrão (sed) [A-Za-z]\+-[0-9]\+, ou seja, um ou mais alfabetos seguidos por um traço (-) seguido por um ou mais números. Eles ocorrem em qualquer lugar da linha.

Preciso extrair os IDs. Meu pensamento foi colocar um .*no início e no final e imprimir \1, mas não consigo fazer funcionar.

Essea resposta diz que sed substitui apenas a primeira correspondência e isso está correto:

$ 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

Mas é claro que um .*titular iria avidamente para a última partida:

$ 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

A única maneira que consigo pensar em fazer isso sedé adicionando marcadores ao redor do ID em um comando e extraindo usando outro, como segue.

Existe uma maneira melhor de fazer isso no 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

Responder1

Com GNU awk, tente:

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

ou:

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

Responder2

Com sed, tente:

<FILE sed -En '/([[:alpha:]]+-[0-9]+).*/{ s//:\1/; s/.*://p; }'
  • Remova tudo após a correspondência desejada
  • Agora a correspondência está no final de cada linha – isso pode ser tratado de várias maneiras
    • O texto acima é facilmente legível – coloque um charque não faça parte da partida antes de cada partida e remova tudo até o último charcom o segundo scomando
    • Outra opção para o segundo scomando é remover tudo até um personagem que não faça parte da partida:
<FILE sed -En '/([[:alpha:]]+-[0-9]+).*/{ s//\1/; s/.*[^[:alnum:]-]//; p; }'

Responder3

Com Perlpodemos fazer da seguinte maneira:

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

saída:

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

informação relacionada