Home > Back-end >  shell code to search between files and copy data from one file to another
shell code to search between files and copy data from one file to another

Time:09-12

I have two big files. file1 has data in below format

place u_RX_WR_SE1_LS { } R0 -place
place u_bank_LS { } R0 -place 

file2 has data in below format

set inst RX_WR_SE1_PD ; add -inst $inst -cell PR ; place $inst  5.76    5305.84 0
set inst RX_WR_SE2_PD ; add -inst $inst -cell PR ; place $inst  5.76    5338.864    0
set inst bank_PD ;  add -inst $inst -cell PR ; place $inst  5.76    5371.888    0

I want to search 2nd field removing starting u_ and _LS from file1 i.e RX_WR_SE1 in file2, and if found in file2, for same match line copy field $13 $14 from file2 and add it inside { } in file1.

The output should be in below format.

place u_RX_WR_SE1_LS { 5.76 5305.84 } R0 -place
place u_bank_LS { 5.76  5371.888 } R0 -place 

Anyone who can help using SHELL? In shell I tried

awk 'FNR==NR{gsub(/u_|_LS/,"",$2);arr[$2]="";next} 
{
for (i in arr) { if ($0 ~ i) {print i,$13,$14}}
}
' file1 file2

but this is not giving proper results.

place RX_WR_SE1 5.76 5305.84 
place bank 5.76  5371.888

CodePudding user response:

1st solution: With your shown samples, please try following awk code; written and tested with shown samples in GNU awk, should work in any awk.

awk '
FNR==NR{
  sub(/_PD$/,"",$3)
  arr["u_"$3]=$(NF-2) OFS $(NF-1)
  next
}
{ temp=$2; sub(/_LS/,"",temp) }
(temp in arr){
  sub(/{/,"&"arr[temp])
  print
}
' file2 file1 

2nd solution: Making different field separators as per samples of Input_file(s) and making use of it with different Input_file(s) to get the required output.

awk '
FNR==NR{
  arr[$3]=$(NF-2) OFS $(NF-1)
  next
}
($3 in arr){
  sub(/{/,"&"arr[$3])
  print
}
' FS='  |_PD' file2 FS=' |u_|_LS' file1

CodePudding user response:

Using any awk:

$ cat tst.awk
NR==FNR {
    sub(/PD$/,"LS",$3)
    map["u_"$3] = $13 OFS $14
    next
}
{
    $3 = $3 OFS map[$2]
    print
}

$ awk -f tst.awk file2 file1
place u_RX_WR_SE1_LS { 5.76 5305.84 } R0 -place
place u_bank_LS { 5.76 5371.888 } R0 -place

or if your input doesn't always have u at the start and PL or LS at the end but could instead have other characters before/after the first/last underscores, then this might be what you need:

$ cat tst.awk
{
    key = ( NR==FNR ? $3 : $2 )
    sub(/_[^_] $/,"",key)
}
NR==FNR {
    map[key] = $13 OFS $14
    next
}
{
    sub(/^[^_] _/,"",key)
    $3 = $3 OFS map[key]
    print
}

$ awk -f tst.awk file2 file1
place u_RX_WR_SE1_LS { 5.76 5305.84 } R0 -place
place u_bank_LS { 5.76 5371.888 } R0 -place

CodePudding user response:

You have made a good attempt at it but need bit of more code to get the output right:

awk '
FNR == NR {
   v = $2
   gsub(/^u_|_LS$/,"",v)
   arr[v] = $0
   next
}
{
   for (i in arr)
      if (index($3, i "_") == 1) {
         sub(/{ }/, "{ " $(NF-2) " " $(NF-1) " }", arr[i])
         print arr[i]
         next
      }
}' file1 file2

place u_RX_WR_SE1_LS { 5.76 5305.84 } R0 -place
place u_bank_LS { 5.76 5371.888 } R0 -place
  • Related