Help search and replace the last occurance of match in a file

Hi I want to replace only the last occurance of "union all" in input file with ";"
I tried with sed 's/union all/;/g' in my input file, it replaced in all lines of input file

Eg:

select column1,column2 from test1 group by 2 union all
 select column1,column2 from test2 group by 2 union all
 select column1,column2 from test3 group by 2 union all  

I need to replace only the last "union all" in the above with ";".

Thanks

One way:

awk '{ arr[NR]=$0; index($0,"union all")>0  {L=NR} }
END { gsub(/union all/, "", arr{L})
          for(i=0; i<NT; i++) 
                    {print arr)
        }'  infile > outfile

There are some errors in the above - thanks Rudi.
See new post below

1 Like

Another way:

ed -s infile <<-EOF
	?union all?s//;/
	w outfile
	q
EOF

where infile and outfile , respective, are pathnames to your input and output files.

You can just use:
	w

instead of:

	w outfile

if you want to update your input file instead of creating a new output file.

1 Like

Thanks for the reply Don cragun
I am working on centos in which ed command not found

Hi antosr7,

This may be one of the methods:

grep "test3" <input_filename> | sed "s/ union all/;/"

where the test3 is the keyword to extract the line and the <filename> is where the three lines can be found.

Hope that this is helpful.

Thank you.

1 Like

Does Centos have the ex utility? If so, for the features I used in the ed script in post #3, ex will work the same way with the same options. On UNIX, Linux, and BSD systems, I usually use ed instead of ex because ex is usually larger and slower to load than ed . The ex utility is bigger because it supplies some extra features that ed doesn't provide, but they aren't used in this script.

1 Like
# expanded lines and fixed errors
awk '{ arr[NR]=$0; 
       if (index($0,"union all")>0)  
       {L=NR} 
     }
END { 
      gsub(/union all/, "", arr[L])
      for(i=0; i<NR; i++) 
             {print arr }
    }'  infile > outfile

1 Like

Hi Jim

Thanks for the code its working in my script

You can use this sed too

sed -E '
:A
N
$!bA
s/(.*)(union all)(.*)/\1;\3/
' infile

A simpler method is

sed  '3 s/ union all/;/' <filename>

where 3 is the line number. This is useful if you know which line to target at, while the grep command will search for all the lines containing the matched pattern(s).

Hope that this is useful.

Cheers.

EDIT:
Just realised that I did not really solve the problem of find and replace "the last occurrence of a match". But hope that my approach can cast a different light on the approaches used to solve your problem.