Estoy tratando de cambiar una sola palabra en una línea específica en un archivo, pero tengo algunos problemas para conectarlos todos juntos.
Básicamente, en una línea de mi archivo hay una palabra clave 'firmware_revision', y en esta línea (y solo en esta línea) quiero reemplazar la palabra 'prueba' con la palabra 'producción'.
Entonces puedo hacer esto:
grep 'firmware_revision' myfile.py | sed 's/test/production'
Esto seleccionará la línea que deseo y realizará la sustitución, pero no puedo encontrar la manera de colocar esta nueva línea en el archivo original para reemplazar la línea anterior. Obviamente no puedo simplemente redirigirlo de nuevo al archivo, entonces, ¿qué debo hacer?
Incluso si uso temporarios, al usar greppara obtener solo la línea que necesito, pierdo todos los demás datos en el archivo, por lo que ya no puedo redirigir todo a un archivo temporal y luego reemplazar el original con la temperatura.
Editar: alguien solicitó más información
Digamos que tengo un archivo lleno de líneas como esta
[
('key_name1', str, 'value1', 'Description'),
('key_name2', str, 'value2', 'Description'),
('key_name3', str, 'value3', 'Description'),
('firmware_revision', str, 'my-firmware-name-test', 'Firmware revision name')
]
ahora quiero escribir un script (idealmente de una línea) que encontrará la línea que contiene 'firmware_revision', y cambia todas las instancias de la palabra 'prueba' en esa línea a 'producción'. La palabra 'prueba' podría estar en otros lugares en ese archivo y no quiero que se cambien. Para que quede claro, quiero cambiar la línea anterior a
('firmware_revision', str, 'my-firmware-name-production', 'Firmware revision name')
¿Cómo hago esto?
fuente

sedes muy potente, puede realizar ambas funciones (grepy sustitución) pero necesitaremos más información sobre cómo se ve la línea para ayudarlo.sed -i.bak '/firmware_revision/ s/test/production/' myfile.pyRespuestas:
Tratar:
Aquí,
/firmware_revision/actúa como una condición. Es cierto para las líneas que coinciden con la expresión regularfirmware_revisiony falso para otras líneas. Si la condición es verdadera, se ejecuta el siguiente comando. En este caso, ese comando es un comando sustituto que reemplaza la primera aparición detestconproduction.En otras palabras, el comando
s/test/production/se ejecuta solo en líneas que coinciden con la expresión regularfirmware_revision. Todas las demás líneas pasan sin cambios.Por defecto, sed envía su salida a la salida estándar. Sin embargo, usted quería cambiar el archivo en su lugar. Entonces, agregamos la
-iopción. En particular,-i.bakhace que el archivo se cambie en su lugar con una copia de seguridad guardada con una.bakextensión.Si ha decidido que el comando funciona para usted y desea vivir peligrosamente y no crear una copia de seguridad, entonces, con GNU sed (Linux), use:
Por el contrario, en BSD (OSX), la
-iopción debe tener un argumento. Si no desea mantener una copia de seguridad, proporcione un argumento vacío. Por lo tanto, use:Editar
En la edición de la pregunta, el OP pide que se sustituya cada aparición
testen la líneaproduction. En ese caso, agregamos lagopción al comando sustituto para un reemplazo global (para esa línea):fuente
-i.bakparte también.-iagregado.sedpueden hacer ...''después-i?sed -i '/firmware_revision/ s/test/production/g' myfile.pycontrario, solo se cambia la primera instancia.En máquinas más antiguas con la vieja escuela
sedque no admite la opción-i:fuente
edy hacerlo en una línea:printf %s\\n g/firmware_revision/s/test/production/g w q | ed -s myfile.pyed(1)no ofrece ningún pretexto para mostrar el uso demktemp(1).edhace. En lugar demv -f "$TF" myfile.plusarcat "$TF" > myfile.pl && rm -f "$TF". Por cierto, es una buena práctica usar nombres de variables en minúsculas (en$tflugar de$TF), se garantiza que no entren en conflicto con ningún vars incorporado en bash (probablemente también otros shells bourne).cat "$TF" > myfile.plprueba esto:touch a b; chmod 0444 a; cat b >a(Por cierto,sed -itampoco funcionará en ese caso). Mejor deje que el usuario se ocupe de eso. Re::rm -f "$TF"no es necesario, vertrap ... EXIT. Re: en$tflugar de$TF: tal vez; Es una cuestión de estilo.umaskdifiere de los permisos originales. En cuanto a los mayúsculas, no es solo una cuestión de estilo: muchas personas que han cometido el error de usar mayúsculas PATH o RANDOM o SHELL o lo que sea para sus propias variables lo han descubierto de la manera difícil. (y sí, a menudo uso mayúsculas también. Sé que está mal, estoy tratando de romper el hábito).