Extraer la primera coincidencia en línea con sed

Extraer la primera coincidencia en línea con sed

Tengo una serie de líneas.

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

Cada línea tiene un ID del patrón (sed) [A-Za-z]\+-[0-9]\+, es decir, uno o más alfabetos seguidos de un guión (-) seguido de uno o más números. Ocurren en cualquier lugar de la línea.

Necesito extraer las identificaciones. Mi idea era colocar un .*al principio y al final e imprimirlo \1, pero no logro que funcione.

Estela respuesta dice que sed reemplaza solo la primera coincidencia y eso es correcto:

$ 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

Pero, por supuesto, un .*comienzo iría con avidez al último partido:

$ 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

La única forma en que se me ocurre hacer esto sedes agregando marcadores alrededor del ID en un comando y extrayéndolo usando otro, de la siguiente manera.

¿Existe una mejor manera de hacer esto en 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

Respuesta1

Con GNU awk, prueba:

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

o:

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

Respuesta2

Con sed, prueba:

<FILE sed -En '/([[:alpha:]]+-[0-9]+).*/{ s//:\1/; s/.*://p; }'
  • Eliminar todo después de la coincidencia deseada.
  • Ahora el partido está al final de cada línea; esto se puede manejar de varias maneras.
    • Lo anterior es fácilmente legible: coloque un charelemento que no sea parte del partido antes de cada partido, luego elimine todo hasta el último charcon el segundo scomando.
    • Otra opción para el segundo scomando es eliminar todo hasta un personaje que no forma parte de la partida:
<FILE sed -En '/([[:alpha:]]+-[0-9]+).*/{ s//\1/; s/.*[^[:alnum:]-]//; p; }'

Respuesta3

Con Perlpodemos hacerlo de la siguiente manera:

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

producción:

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

información relacionada