Como adicionar uma linha específica em um arquivo ao final da linha específica em outro arquivo? (use sed talvez)

Como adicionar uma linha específica em um arquivo ao final da linha específica em outro arquivo? (use sed talvez)

Eu tenho um arquivo 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 

Neste arquivo supermaster.PRM, quero pegar o ' rng_samp_rate = 64345238.125714 ' - sei que existem dois, mas só preciso de um - para colocá-lo neste 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

até o final da linha 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

Responder1

Você pode 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

O primeiro arquivo deve ser o arquivo de parâmetros, o segundo arquivo o script de shell a ser modificado. (Este awkscript usa a última ocorrência de rng_samp_rate.)

A saída é

#!/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

Claro que você também pode usar outras ferramentas como grepe sed.

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

ou talvez um pouco mais fácil de entender

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

(Aqui eu uso a primeira ocorrência de rng_samp_rate.)

Ambos os comandos assumem que nenhuma outra linha começa com rng_samp_rateou sbase que o arquivo de parâmetro sempre contém uma rng_samp_ratelinha. O sedscript pressupõe que a linha de valor do arquivo de parâmetro não contém um arquivo /.


Editar: Como modificar o arquivo de script em vez de criar um novo arquivo de saída?

Alguns comandos, por exemplo sed, suportam edição no local que você pode usar para modificar o arquivo de script sem criar explicitamente um arquivo de saída separado.

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

Em geral você sempre pode seguir o comando com um mvcomando adequado, por exemplo

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

Isso &&garante que seu script original seja substituído somente se o awkcomando não indicar um erro.

Se quiser fazer mais modificações você pode estender o script awkou sed(melhor desempenho) ou executar vários scripts sequencialmente ou conectados a um pipe. (Para obter detalhes, você deve escrever os requisitos adicionais.)

Responder2

Você poderia criar um script com ed:

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

Isso altera a (primeira) linha que começa com o texto " sbas" para acrescentar um espaço e um travessão. Em seguida, ele lê a saída de um comando shell para a linha subsequente; o comando shell procura o texto " rng_samp_rate" no início da linha em supermaster.PRM e usa head -1para obter apenas o primeiro resultado. Essa saída é então unida à linha anterior. Em seguida, salvamos o arquivo no disco e saímos.

Se os espaços adicionais do texto original forem um problema, você pode reduzi-los modificando ligeiramente o código do shell:

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

... que apenas adiciona um sedcomando que substitui 1 ou mais espaços por um único espaço. Se espaços extras puderem ocorrer após o sinal de igual, altere o comando sed para: sed 's/ */ /g'.

informação relacionada