Wie fügt man eine bestimmte Zeile in einer Datei an das Ende einer bestimmten Zeile in einer anderen Datei an? (verwenden Sie ggf. sed)

Wie fügt man eine bestimmte Zeile in einer Datei an das Ende einer bestimmten Zeile in einer anderen Datei an? (verwenden Sie ggf. sed)

Ich habe eine Datei 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 

In dieser Datei supermaster.PRM möchte ich „rng_samp_rate = 64345238.125714“ nehmen – ich weiß, dass es zwei gibt, aber ich brauche nur eine – und sie in dieses Shell-Skript einfügen:

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

bis zum Ende der sbas-Zeile wie

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

Antwort1

awkSie können dieses Skript verwenden :

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

Die erste Datei muss die Parameterdatei sein, die zweite Datei das zu ändernde Shell-Skript. (Dieses awkSkript nimmt das letzte Vorkommen von rng_samp_rate.)

Die Ausgabe ist

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

Natürlich können Sie auch andere Tools wie grepund verwenden sed.

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

oder vielleicht ein bisschen leichter zu verstehen

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

(Hier verwende ich das erste Vorkommen von rng_samp_rate.)

Beide Befehle gehen davon aus, dass keine anderen Zeilen mit rng_samp_rateoder beginnen sbasund dass die Parameterdatei immer eine rng_samp_rateZeile enthält. Das sedSkript geht davon aus, dass die Wertezeile aus der Parameterdatei kein enthält /.


Bearbeiten: Wie ändere ich die Skriptdatei, anstatt eine neue Ausgabedatei zu erstellen?

Einige Befehle, z. B. sed, unterstützen die Bearbeitung direkt, mit der Sie die Skriptdatei ändern können, ohne explizit eine separate Ausgabedatei zu erstellen.

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

Generell kann man dem Befehl immer einen passenden mvBefehl folgen lassen, zB

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

Dadurch &&wird sichergestellt, dass Ihr Originalskript nur dann überschrieben wird, wenn der awkBefehl keinen Fehler angezeigt hat.

Wenn Sie weitere Änderungen vornehmen möchten, können Sie das Skript erweitern awk( sedoptimale Leistung) oder mehrere Skripte nacheinander oder verbunden mit einer Pipe ausführen. (Details entnehmen Sie bitte den zusätzlichen Anforderungen.)

Antwort2

Sie könnten dies mit folgendem Skript skripten ed:

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

Dies ändert die (erste) Zeile, die mit dem Text " sbas" beginnt, um ein Leerzeichen und einen Bindestrich anzuhängen. Anschließend wird die Ausgabe eines Shell-Befehls in die folgende Zeile gelesen. Der Shell-Befehl sucht rng_samp_ratein supermaster.PRM nach dem Text " " am Anfang der Zeile und verwendet dann, head -1um nur das erste derartige Ergebnis abzurufen. Diese Ausgabe wird dann mit der vorherigen Zeile verknüpft. Anschließend speichern wir die Datei auf der Festplatte und beenden das Programm.

Wenn die zusätzlichen Leerzeichen im Originaltext ein Problem darstellen, können Sie sie durch eine leichte Änderung des Shell-Codes entfernen:

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

... fügt lediglich einen sedBefehl hinzu, der ein oder mehrere Leerzeichen durch ein einzelnes Leerzeichen ersetzt. Wenn nach dem Gleichheitszeichen zusätzliche Leerzeichen auftreten können, ändern Sie den sed-Befehl wie folgt: sed 's/ */ /g'.

verwandte Informationen