あるファイルの特定の行を別のファイルの特定の行の末尾に追加するにはどうすればよいですか? (sed を使用するとよいでしょう)

あるファイルの特定の行を別のファイルの特定の行の末尾に追加するにはどうすればよいですか? (sed を使用するとよいでしょう)

ファイルがあります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 

この supermaster.PRM ファイルでは、「 rng_samp_rate = 64345238.125714 」 (2 つあることはわかっていますが、必要なのは 1 つだけです) を取得して、次のシェル スクリプトに入力します。

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

sbas行の終わりのように

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

答え1

次のスクリプトを使用できますawk:

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

最初のファイルはパラメータ ファイルで、2 番目のファイルは変更するシェル スクリプトである必要があります。(このawkスクリプトは、 の最後の出現を取得しますrng_samp_rate。)

出力は

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

もちろん、grepや などの他のツールも使用できますsed

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

あるいはもう少し分かりやすく

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

(ここでは の最初の出現を使用しますrng_samp_rate。)

どちらのコマンドも、他の行がrng_samp_rateまたはで始まっていないことsbas、およびパラメータ ファイルには常にrng_samp_rate行が含まれていることを前提としています。sedスクリプトは、パラメータ ファイルの値行に が含まれていないことを前提としています/


編集: 新しい出力ファイルを作成する代わりに、スクリプト ファイルを変更するにはどうすればよいですか?

一部のコマンド (例: sed) はインプレース編集をサポートしており、これを使用すると、別の出力ファイルを明示的に作成せずにスクリプト ファイルを変更できます。

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

一般的には、コマンドの後に適切なコマンドを続けることができますmv。例:

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

コマンドがエラーを示さなかった&&場合にのみ、元のスクリプトが上書きされるようになります。awk

さらに変更を加えたい場合は、awkまたはsedスクリプトを拡張するか (最高のパフォーマンス)、複数のスクリプトを順番に実行したり、パイプに接続したりすることができます。 (詳細については、追加の要件を記述する必要があります。)

答え2

これを次のようにスクリプト化できますed:

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

これにより、テキスト " sbas" で始まる (最初の) 行が変更され、スペースとダッシュが追加されます。次に、シェル コマンドからの出力が次の行に読み込まれます。シェル コマンドは、rng_samp_ratesupermaster.PRM の行の先頭にあるテキスト " " を検索し、 を使用してhead -1最初の結果のみを取得します。その出力は、前の行と結合されます。次に、ファイルをディスクに保存して終了します。

元のテキストの余分なスペースが問題になる場合は、シェル コードを少し変更してスペースを削減できます。

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

... これは、sed1 つ以上のスペースを 1 つのスペースに置き換えるコマンドを追加するだけです。等号の後に余分なスペースが発生する可能性がある場合は、sed コマンドを次のように変更しますsed 's/ */ /g'

関連情報