4 votos

¿Cómo reemplazar un campo determinado de un archivo basado en el contenido de otro campo?

Tengo un archivo con el siguiente formato:

A 485C72F95C72E15C EXTERNAL
B CC32480A3247F84A SYSTEM
C EC2A63F12A63B76C EXTERNAL

Quiero la oferta de la carta, en la primera columna con el valor de la variable 'carta', y reemplazar el valor de la segunda columna con un valor de la oferta en la variable 'id'. La tercera columna puede o no puede diferir o partido en cualquier caso. La primera y la segunda columnas nunca va a contener espacios ni caracteres especiales.

He intentado utilizar sed, pero mi sed-fu no es fuerte. Se me ocurrió esto:

letter=A
id=MYNEWIDSTRING
sed "/$letter /s/[^ ]*/$id/2"

El resultado es:

A MYNEWIDSTRING EXTERNAL
B MYNEWIDSTRING SYSTEM
C EC2A63F12A63B76C EXTERNAL

El id se sustituye en dos líneas, estoy suponiendo que esto es debido a la 'a' se igualó en el final de la original cadena de id.

Yo sé usar sed -i a editar el archivo directamente, pero no hacerlo, sin embargo, como mi mando es un poco cutre.

Donde he ido mal, o debo utilizar un método diferente?

5voto

Zanna Puntos 502

Anclaje ( ^ es principio de línea) para que la "A" sólo es igualada si es el primer personaje:

$ letter=A; id=MYNEWIDSTRING; sed "/^$letter /s/[^ ]*/$id/2" file
A MYNEWIDSTRING EXTERNAL
B CC32480A3247F84A SYSTEM
C EC2A63F12A63B76C EXTERNAL

por cierto, si quieres pasar variables a sed pero usted necesita cotizar fuerte recordar puede activar citando a encendido y apagado al mismo tiempo agregar comillas dobles para las variables - feos pero probablemente mejores prácticas en general:

sed '/^'"$letter"' /s/[^ ]*/'"$id"'/2'

5voto

steeldriver Puntos 19092

Cada vez que se trata de datos estructurados , alcanzaría para awk o perl en lugar de sed .

Por ejemplo

awk -v letter="A" -v id="MYNEWIDSTRING" '$1 == letter {$2=id}1' file
A MYNEWIDSTRING EXTERNAL
B CC32480A3247F84A SYSTEM
C EC2A63F12A63B76C EXTERNAL

o

perl -alne '
  BEGIN{$letter = shift; $id = shift;} 
  print join " ", $F[0], $F[0] eq $letter ? $id : $F[1], @F[2..$#F]
' 'A' 'MYNEWIDSTRING' file

Versiones más recientes de awk de GNU tienen un -i ( --in-place ) flag; en otros necesita utilizar un archivo temporal explícito perl debe tener un -i en cualquier caso.

EnMiMaquinaFunciona.com

EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.

Powered by: