Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

270
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda