Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

272
Vistas
Linux bash: ¿Cómo reemplazo una cadena en una línea basada en un patrón en otra línea diferente?

Tengo un archivo que contiene los siguientes datos:

 GS*PO*112233*445566*20211006*155007*2010408*X*004010~ ST*850*0001~ BEG*00*DS*A-112233**20211005~ REF*K6*Drop Ship Order~ REF*ZZ*SO168219~ REF*DC*ABC~ ST*850*0002~ BEG*00*DS*A-44556**20211005~ REF*K6*Drop Ship Order~ REF*ZZ*PO54361~ ST*850*0003~ BEG*00*DS*A-12345**20211005~ REF*K6*Drop Ship Order~ REF*DC*XYZ~ REF*ZZ*SO897654~

Para mayor claridad, he insertado una línea en blanco encima de cada línea ST*850 . Esto es lo que quiero hacer:

  1. Busca el patrón REF*ZZ*SO
  2. Si lo encuentra, reemplace la línea anterior ST*850 con ST*850C

Así que el archivo resultante se vería así:

 GS*PO*112233*445566*20211006*155007*2010408*X*004010~ ST*850C*0001~ BEG*00*DS*A-112233**20211005~ REF*K6*Drop Ship Order~ REF*ZZ*SO168219~ REF*DC*ABC~ ST*850*0002~ BEG*00*DS*A-44556**20211005~ REF*K6*Drop Ship Order~ REF*ZZ*PO54361~ ST*850C*0003~ BEG*00*DS*A-12345**20211005~ REF*K6*Drop Ship Order~ REF*DC*XYZ~ REF*ZZ*SO897654~

Esto es lo que he probado:

 sed -i -n '/^REF\*ZZ\*SO/!{x;s/ST\*850\*/ST\*850C\*/;x};x;1!p;${x;p}' file

Esto reemplaza las tres líneas ST*850 con ST*850C y no solo la primera y la tercera. ¿Qué estoy haciendo mal?

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Esto podría funcionar para usted (GNU sed):

 sed '/ST\*850/{:a;/REF\*ZZ\*SO/!{N;ba};s/.*ST\*850/&C/}' file

Comience a recopilar líneas si una línea contiene ST*850 .

Al hacer coincidir una línea que contiene REF*ZZ*SO use greed para agregar C a la última cadena ST*850 .

NB La expresión regular .* asegura que la coincidencia retrocederá desde el final de la colección en lugar del inicio de la colección.

over 4 years ago · Santiago Trujillo Denunciar

0

¿Qué tal una solución perl aunque perl no está incluido en las etiquetas?

 perl -0777 -aF'(?=ST\*850)' -ne ' print map {/REF\*ZZ\*SO/ && s/ST\*850/$&C/; $_} @F; ' file

Producción:

 GS*PO*112233*445566*20211006*155007*2010408*X*004010~ ST*850C*0001~ BEG*00*DS*A-112233**20211005~ REF*K6*Drop Ship Order~ REF*ZZ*SO168219~ REF*DC*ABC~ ST*850*0002~ BEG*00*DS*A-44556**20211005~ REF*K6*Drop Ship Order~ REF*ZZ*PO54361~ ST*850C*0003~ BEG*00*DS*A-12345**20211005~ REF*K6*Drop Ship Order~ REF*DC*XYZ~ REF*ZZ*SO897654~
  • La opción -0777 le dice a perl que sorba todo el archivo a la vez.
  • La opción -a habilita el modo de auto split , luego los fragmentos divididos se almacenan en la matriz @F .
  • La opción -F especifica el patrón para dividir la entrada.
  • La expresión regular (?=ST\*850) es una búsqueda positiva que coincide con el comienzo de una cadena ST*850 .
  • La opción -ne es mayormente equivalente a la de sed .
  • La función map {..} @F convierte todos los elementos de @F de acuerdo con la declaración entre llaves.
  • La declaración /REF\*ZZ\*SO/ && s/ST\*850/$&C/ se traduce como: "si el elemento de @F coincide con el patrón /REF*ZZ*SO/, entonces realice la sustitución s/ ST*850/$&C/ para el elemento".
  • El $_ final es la variable predeterminada de perl similar al pattern space de sed y serán los valores de retorno de la función de mapa.
over 4 years ago · Santiago Trujillo Denunciar

0

Suponiendo que ST es esencialmente un separador de registros, puede usar un script Awk simple para recopilar las líneas en el registro actual e imprimir uno diferente modificado si las condiciones son adecuadas.

 awk 'BEGIN { ORS = RS = "\nST" } /REF\*ZZ\*SO/ { sub(/^\*850/, "*<850C") }1' filename

La cláusula BEGIN establece el separador de registros ( RS ) y también el separador de registros de salida ( ORS ) en la cadena ST precedida por una nueva línea. (Intentar incluir el asterisco se complicó, así que lo evité). El 1 final es la abreviatura común de Awk para "imprimir todo lo que llega aquí".

sed es bastante difícil de manejar para cualquier cosa más allá de simples sustituciones basadas en líneas; Creo que encontrará que cambiar a un lenguaje de nivel superior mejorará la capacidad de mantenimiento.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda