Busque una parte del texto en una línea y luego agréguela a otra parte de la misma línea

Busque una parte del texto en una línea y luego agréguela a otra parte de la misma línea

Tengo esto:

Issue #12345: some more text here https://some.domain/some/path

Me gustaría encontrar el bit 12345 (que es dinámico, por lo que deberá ser mediante una expresión regular) y luego agregarlo al final de la misma línea. Al igual que:

Issue #12345: some more text here https://some.domain/some/path/12345

¿Cómo puedo lograr eso usando sed/awk?

PD: He mirado a mi alrededor, pero la única pregunta similar fue esta:Reemplazar parte de una cuerda con otra parte de esa misma cuerda...pero le falta el bit de expresión regular.

Respuesta1

Suponiendo que su entrada esté en un archivo test.txt, el siguiente comando debería funcionar

sed -E 's/^(.*)([[:digit:]]{5})(.*)$/\1\2\3\/\2/g' test.txt

Si no está leyendo directamente desde un archivo,

input_source | sed -E 's/^(.*)([[:digit:]]{5})(.*)$/\1\2\3\/\2/g'

Producción:

Issue #12345: some more text here https://some.domain/some/path/12345

Qué hace el comando:

^(.*)Comience desde el principio del archivo y tome todo hasta la siguiente coincidencia, ([[:digit:]]{5})coincida con los siguientes 5 dígitos, (.*)$tome todo hasta el final del archivo, \1\2\3\/\2cada grupo coincidente está numerado (1-3 en este caso) y formateamos la salida para obtener el texto original. (partidos 1-3), '/' y luego el segundo partido.

Para referencia futura, sería ideal si pudiera describir su problema de manera más concreta. Por ejemplo, digamos que está buscando los primeros 5 dígitos de una línea y desea agregar estos dígitos (con una barra diagonal anterior) al final de la línea, y haga esto para cada línea de la entrada. Supuse que esto es lo que querías decir. De lo contrario, es posible que desee actualizar su pregunta para que sea más específica.

Quizás también quieras enumerar algunos intentos que hiciste en lugar de simplemente citar preguntas anteriores. También nos ayuda a tener una mejor idea de lo que está intentando hacer.

Respuesta2

sed 's,\([[:digit:]][[:digit:]]*\).*,&/\1,' file

o, si sedtiene que -Elidiar con expresiones regulares extendidas en patrones,

sed -E 's,([[:digit:]]+).*,&/\1,' file

La sedexpresión de sustitución encuentra el primer número entero positivo (cadena de dígitos) en la línea y lo captura. También coincide con el resto de la línea desde ese punto hasta el final de la línea. La parte de reemplazo de la expresión reemplaza el bit coincidente de la línea con todo lo que coincidió ( &), seguido de una barra y la cadena de dígitos capturada.

Estoy usando comas como delimitador en la expresión ya que la pieza de reemplazo contiene una barra, pero también podría haber escrito el comando como

sed -E 's/([[:digit:]]+).*/&\/\1/' file

Los comandos anteriores realizarían la sustitución en todas las líneas de entrada. Para restringirlo a líneas que solo comienzan con la cadena Issue #, use

sed -E '/^Issue #/s,([[:digit:]]+).*,&/\1,' file

Respuesta3

Lo he hecho por el siguiente método

dominio

i=`awk '{print $2}' file.txt| sed "s/^#//g"| sed "s/:$//g"`
awk -v i="$i" '{print $0"/"i}' filetxt

producción

Issue #12345: some more text here https://some.domain/some/path/12345

información relacionada