¿Cómo agregar una línea específica en un archivo al final de la línea específica en otro archivo? (Quizás use sed)

¿Cómo agregar una línea específica en un archivo al final de la línea específica en otro archivo? (Quizás use sed)

Tengo un archivo supermaster.PRM:

num_valid_az    = 12194 
nrows           = 12194 
first_line          = 1 
deskew          = n 
caltone         = 0.000000 
st_rng_bin          = 1 
Flip_iq         = n 
offset_video    = n 
az_res          = 0.000000 
nlooks          = 1 
chirp_ext           = 0 
scnd_rng_mig    = 0 
rng_spec_wgt    = 1.000000 
rm_rng_band         = 0.200000 
rm_az_band          = 0.000000 
rshift          = -18 
ashift          = 0 
stretch_r           = 0 
stretch_a           = 0 
a_stretch_r     = 0 
a_stretch_a     = 0 
first_sample    = 284 
SC_identity         = 10 
rng_samp_rate       = 64345238.125714 
input_file      = S1_20160114_ALL_F1.raw 
num_rng_bins        = 67752 
bytes_per_line      = 271008 
good_bytes_per_line = 271008 
PRF         = 486.486310 
pulse_dur       = 5.240481e-05 
near_range      = 799926.599409 
num_lines       = 12194 
num_patches     = 1 
SC_clock_start      = 2016013.0823712260 
SC_clock_stop       = 2016013.0826613354 
clock_start     =  13.082371226227 
clock_stop          =  13.082661335643 
led_file        = S1_20160114_ALL_F1.LED 
orbdir  = A 
lookdir = R 
radar_wavelength    = 0.0554658 
chirp_slope = 1.07815e+12 
rng_samp_rate       = 64345238.125714 
I_mean          = 0 
Q_mean          = 0 
SC_vel          = 7160.742699 
earth_radius        = 6371038.614500 
equatorial_radius   = 6378137.000000 
polar_radius        = 6356752.310000 
SC_height       = 699860.307600 
SC_height_start = 699988.203956 
SC_height_end   = 699732.953774 
fd1         = 0.000000 
fdd1            = 0.000000 
fddd1           = 0.000000 
sub_int_r               = 0.000000 
sub_int_a               = 0.000000 
SLC_file               = S1_20160114_ALL_F1.SLC 
dtype           = a 
SLC_scale               = 1.000000 

En este archivo supermaster.PRM, quiero tomar 'rng_samp_rate = 64345238.125714' (sé que hay dos, pero solo necesito uno) para ponerlo en este script de shell:

#!/bin/bash
#SBATCH --job-name=InSAR
#SBATCH --ntasks=128
#SBATCH --time=7-00:00:00
#SBATCH --mail-type=fail,end
#SBATCH --export=all
#SBATCH --out=Forge-%j.out
#SBATCH --mem=256000

module load GMT
module load GMTSAR
module load parallel
sbas intf.tab scene.tab 19 10 8469 6097 
csh plot_sbas.csh

hasta el final de la línea sbas como

#!/bin/bash
#SBATCH --job-name=InSAR
#SBATCH --ntasks=128
#SBATCH --time=7-00:00:00
#SBATCH --mail-type=fail,end
#SBATCH --export=all
#SBATCH --out=Forge-%j.out
#SBATCH --mem=256000

module load GMT
module load GMTSAR
module load parallel
sbas intf.tab scene.tab 19 10 8469 6097 -rng_samp_rate = 64345238.125714
csh plot_sbas.csh

Respuesta1

Puedes usar este awkscript:

awk 'NR==FNR && /^rng_samp_rate/ { value=$0 } 
     NR!=FNR && !/^sbas/         { print }
     NR!=FNR && /^sbas/          { print $0 " -" value }' supermaster.PRM script.in > script.out

El primer archivo debe ser el archivo de parámetros y el segundo, el script de shell que se va a modificar. (Este awkscript toma la última aparición de rng_samp_rate.)

La salida es

#!/bin/bash
#SBATCH --job-name=InSAR
#SBATCH --ntasks=128
#SBATCH --time=7-00:00:00
#SBATCH --mail-type=fail,end
#SBATCH --export=all
#SBATCH --out=Forge-%j.out
#SBATCH --mem=256000

module load GMT
module load GMTSAR
module load parallel
sbas intf.tab scene.tab 19 10 8469 6097  -rng_samp_rate       = 64345238.125714 
csh plot_sbas.csh

Por supuesto, también puedes utilizar otras herramientas como grepy sed.

sed "s/^sbas.*/& -$(grep '^rng_samp_rate' supermaster.PRM|head -1)/" script.in > script.out

o tal vez un poco más fácil de entender

#! /bin/sh
VALUE="$(grep '^rng_samp_rate' supermaster.PRM|head -1)"
sed "s/^sbas.*/& -$VALUE/" script.in > script.out

(Aquí uso la primera aparición de rng_samp_rate.)

Ambos comandos asumen que ninguna otra línea comienza con rng_samp_rateo sbasy que el archivo de parámetros siempre contiene una rng_samp_ratelínea. El sedscript supone que la línea de valor del archivo de parámetros no contiene un archivo /.


Editar: ¿Cómo modificar el archivo de secuencia de comandos en lugar de crear un nuevo archivo de salida?

Algunos comandos, por ejemplo sed, admiten la edición in situ que puede utilizar para modificar el archivo de secuencia de comandos sin crear explícitamente un archivo de salida independiente.

sed  -i .bak -e "some script" script.in

En general, siempre puedes seguir el comando con un mvcomando adecuado, por ejemplo

awk 'some script' supermaster.PRM script.in > script.out && mv script.out script.in

Esto &&garantiza que su secuencia de comandos original se sobrescriba solo si el awkcomando no indicó un error.

Si desea hacer más modificaciones, puede ampliar el script awko sed(mejor rendimiento) o ejecutar varios scripts de forma secuencial o conectados a una tubería. (Para más detalles debe escribir los requisitos adicionales).

Respuesta2

Podrías escribir esto con ed:

printf '%s\n' \
  '/^sbas /s/$/ -/' \
  '. r !grep ^rng_samp_rate supermaster.PRM | head -1' \
  '-1,.j' \
  'w' \
  'q' | ed -s shellscript

Esto cambia la (primera) línea que comienza con el texto " sbas" para agregar un espacio y un guión. Luego lee la salida de un comando de shell en la línea siguiente; el comando de shell busca el texto " rng_samp_rate" al principio de la línea en supermaster.PRM y luego lo utiliza head -1para obtener solo el primer resultado. Luego, esa salida se une a la línea anterior. Luego guardamos el archivo en el disco y salimos.

Si los espacios adicionales del texto original son un problema, puedes exprimirlos modificando ligeramente el código de shell:

...
grep ^rng_samp_rate supermaster.PRM | head -1 | sed 's/  */ /'
...

... que simplemente agrega un sedcomando que reemplaza 1 o más espacios con un solo espacio. Si pueden aparecer espacios adicionales después del signo igual, cambie el comando sed a: sed 's/ */ /g'.

información relacionada