![如何将一个文件中的特定行添加到另一个文件中的特定行的末尾?(可以使用sed)](https://linux22.com/image/171204/%E5%A6%82%E4%BD%95%E5%B0%86%E4%B8%80%E4%B8%AA%E6%96%87%E4%BB%B6%E4%B8%AD%E7%9A%84%E7%89%B9%E5%AE%9A%E8%A1%8C%E6%B7%BB%E5%8A%A0%E5%88%B0%E5%8F%A6%E4%B8%80%E4%B8%AA%E6%96%87%E4%BB%B6%E4%B8%AD%E7%9A%84%E7%89%B9%E5%AE%9A%E8%A1%8C%E7%9A%84%E6%9C%AB%E5%B0%BE%EF%BC%9F%EF%BC%88%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8sed%EF%BC%89.png)
我有一个文件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 ”——我知道有两个,但我只需要一个——将其放入这个 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
到 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
第一个文件必须是参数文件,第二个文件是要修改的shell脚本。 (此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
or开头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
”开头的(第一)行,以附加空格和破折号。然后,它将 shell 命令的输出读取到下一行; shell 命令rng_samp_rate
在 supermaster.PRM 的行开头搜索文本“ ”,然后head -1
仅获取第一个此类结果。然后将该输出与前一行连接起来。然后我们将文件保存到磁盘并退出。
如果原始文本中的额外空格是一个问题,您可以通过稍微修改 shell 代码来压缩它们:
...
grep ^rng_samp_rate supermaster.PRM | head -1 | sed 's/ */ /'
...
...它只是添加一个sed
用一个空格替换 1 个或多个空格的命令。如果等号后面可能出现额外的空格,请将 sed 命令更改为:sed 's/ */ /g'
。