Find and replace values using a list from a file

Hello Guys.

I have a very big file where I need to change some values according a list on other file.

The following file is were I have the values to be changed.

The field where I need to replace the values is

    File_Nb             : 

File1.txt

Obs_Report_Result : [
]
# ===== (5) =====
Observer_Report : [
# ===============

  Version         : "5.0"
  Exploitation_Mode     : SLIP SWEEP

  Line_Report     : [
    Filter_Type             : 8N LIN
    Aux_Nb_Trace         : 5
    Seis_Nb_Trace         : 3840
    Total_Nb_Trace         : 3845
    Nb_Of_Dead_Seis_Channels     : 0
    Nb_Of_Live_Seis_Channels     : 3840
    Dead_Seis_Channels         : 
    Live_Seis_Channels         : 6260:4578-5056(1-240)    
                             6270:4578-5056(241-480)    
                             6280:4578-5056(481-720)    
                             6290:4578-5056(721-960)    
                             6300:4578-5056(961-1200)    
                             6310:4578-5056(1201-1440)    
                             6320:4578-5056(1441-1680)    
                             6330:4578-5056(1681-1920)    
                             6340:4578-5056(1921-2160)    
                             6350:4578-5056(2161-2400)    
                             6360:4578-5056(2401-2640)    
                             6370:4578-5056(2641-2880)    
                             6380:4578-5056(2881-3120)    
                             6390:4578-5056(3121-3360)    
                             6400:4578-5056(3361-3600)    
                             6410:4578-5056(3601-3840)
    SFL                 : 6260
    SFN                 : 4578
    Spread_Nb             : 351
    Spread_Type             : ABSOLUTE
    Acq_Error             : 
    ITB                 : FALSE
  ]

  Shot_Report     : [
    Swath_Name             : 2146
    Swath_ID             : 46
    Shot_Nb             : 532
    Line_Name             :  6333.0
    Point_Number         :  4817.0
    Point_Index             : 1
    Acq_Length             : 18000 # (msec)
    Sweep_Length         : 12000 # (ms)
    Pilot_Length         : 12000 # (ms)
    Record_Length         : 6000 # (ms)
    Sample_Rate             : 2000
    Total_Nb_Sample         : 3001
    Type_Of_Source         : VIBRO
    Source_Nb             : 3
    Tb_Window             : 20000
    Date             : Fri Nov 22 06:54:47 2013

    Julian_Day             : 326
    Cog_State             : ACTUAL
    Cog_Easting             : 747980.7
    Cog_Northing         : 2521522.4
    Cog_Elevation         : 500.0
    Cog_Deviation         :    2.4
    Uphole_Time             :  0.00 # (msec)
  ]

  Noise_Report     : [
    Noise_Elim_type         : NE OFF
    Thres_Hold_Var         : N/A
    Hist_Editing_Type         : N/A
    Hist_Range             : N/A # (dB)
    Hist_Taper_Length         : N/A # (power)
    Hist_Thres_Init_Val         : N/A # (dB)
    Hist_Zeroing_Length         : N/A # (msec)
    Low_Trace_Value         : 0 # (dB)
    Low_Trace_Percent         : 0
    Noisy_Trace_Percent         : N/A
    Low_Noisy_Verbose         : 
    Nb_Of_Window         : 0
  ]

  Process_Report     : [
    Type_Of_Process         : CORREL BEFORE
    Acq_Nb             : 1
    Correl_Pilot_Nb         : 3
    Auto_Cor_Peak_Time         : 1000
    Dump_Stacking_Fold         : 1
    Max_Of_Max_Aux_Char         : "   2.444985e+16"
    Max_Of_Max_Seis_Char     : "   3.784387e+14"
    Max_Time_Value_Verbose     : "0/1 : 0 454696.31"
    Tb_GPS_Time             : 1069127704236001
  ]

  Record_Report         : [
    File_Nb             : 1021
    Type_Of_Dump         : DUMP
    Type_Of_Test         : N/A 3
    Tape_Nb             : 408
    Tape_Label             : "N9"
    Record_Type             : NORMAL
    Blocking_Mode         : FALSE
    Device_Bypass         : FALSE
    Tape_Error_Text         : ""
    Tape_Time             : "Fri Nov 22 06:55:09 2013
"
    File_Count             : "955
    File_Per_Tape         : "9999"
  ]

  Comment             : "N/A"
  User_Header             : ""
  

In the other file2.txt I have the values to be changed and the new value to be used.

529   959
530   952
531   953
1010  1200
1021  1201

Example.

    File_Nb             : 1021

shouldbe changed to

    File_Nb             : 1201

I need to replace a lot of numbers and the original file is very big.

I have attached both files.

Thanks a lot for your help

Try this:

awk 'NR==FNR{a[$1]=$2; next} /File_Nb/{$NF=a[$NF]}1' file2 file1
1 Like

It does not work :(, give a syntax error??

I don't see any syntax error in Subbeh's awk program. If you are on SunOS or Solaris try using nawk or /usr/xpg4/bin/awk instead.

1 Like

Hi Yoda,, yes there no error i was typing bad... but the code dont works I I want.. :frowning:

I ran it on the files that you attached and I got what you want!

$ grep File_Nb file1.txt
    File_Nb                      : 529
    File_Nb                      : 530
    File_Nb                      : 531
    File_Nb                      : 1010
    File_Nb                      : 1021

$ awk 'NR==FNR{a[$1]=$2; next} /File_Nb/{$NF=a[$NF]}1' file2.txt file1.txt | grep File_Nb
File_Nb : 959
File_Nb : 952
File_Nb : 953
File_Nb : 1200
File_Nb : 1201
1 Like

Thanks Yoda..

How can I keep the same format in the output file?
File_Nb : 529
Regards

Please note that an awk program never modifies the content of original input file. So you have to redirect the output to a temporary file and rename it back to original file:

awk ... file1.txt > tmp; mv tmp file1.txt
1 Like

In the output i got:
File_Nb : 529

I would like to get

    File_Nb             : 529               

Same format of the original file

Thansk for your help :b:

---------- Post updated at 02:42 PM ---------- Previous update was at 02:40 PM ----------

Yoda Thanks a lot for your help..
Yes I did it but the format as changed and I would like to keep the same format of the original file...

I'm sorry, I misread what you requested.

Replace $NF=a[$NF] with sub(/:[ ].*$/,": "a[$NF])

awk 'NR==FNR{a[$1]=$2; next} /File_Nb/{sub(/:[ ].*$/,": "a[$NF])}1' file2 file1
1 Like

Give this a shot (based on Subbeh's proposal):

awk 'NR==FNR{gsub(/ /,"",$2); a[$1]=$2; next} /File_Nb/{gsub(/ /,"",$NF); $NF=" "a[$NF]}1' file2 FS=":" OFS=":" file1
1 Like

@Rudi: What are the gsub() for?

You are right, the first one is not needed. You need the second one because FS=":" will leave the space in so $NF will not be found in array a . So this should do

awk 'NR==FNR{a[$1]=$2; next} /File_Nb/{gsub(/ /,"",$NF); $NF=" "a[$NF]}1' file2 FS=":" OFS=":" file
1 Like

Many Thanks to all :b:

sed, something like this?

sed "$( while read a b
do
  echo "s/\\<$a\\>/$b/"
done <file2.txt )" file1.txt
1 Like

An attempt to avoid string ops and full-line matches

awk 'NR==FNR {a[$1]=$2; next}
$1~/File_Nb/ && ($NF in a) {sub($NF,a[$NF])}
1' file2 file1
2 Likes

@MadeInGermany: good point! But then, shouldn't sub($NF,a[$NF]) read sub($NF, a[$NF], $NF) to avoid the full line match?

1 Like

Thanks to all for your help

Unfortunately, if the sub() target is a field string $NF, it causes a reformatting of $0 (just like $NF="string").

---------- Post updated at 09:37 AM ---------- Previous update was at 09:27 AM ----------

Interesting idea. But should at least match /File_Nb/ somewhere

sed "$( while read a b
do
  echo '/File_Nb/ s/\<$a\>/$b/'
done <file2.txt )" file1.txt
1 Like

Writing scripts that write scripts is neato!