using sed to replace a specific string on a specific line number using variables

using sed to replace a specific string on a specific line number using variables

this is where i am at

grep -v WARNING output | grep -v spawn | grep -v Passphrase | grep -v Authentication | grep -v '/sbin/tfadmin netguard -C'| grep -v 'NETWORK>' >> output.clean
grep -n Destination output.clean > output.1
awk -F : '{print $1}' < output.1 > output.2
for y in `cat output.2`; do
for port in `cat portlist` ; do
echo $y
sed -e "'$y's/Destination Port matches/Dest port match $port/" < output.clean >> output.3

    done

done

where the first grep cleans out the file of junk, the second one gets the line numbers i need to look at, awk cleans that file quick, and sed is supposed to use the values to find the line number and grep place it with the text of which $port being var that gets assigned.

Many thanks!

ps: i am a complete rookie

Your code does not seem to match the logic.
The outer for loops through line numbers in output.2 (say, 1,2).
The inner for loops through port numbers (?) in portlist (say, 10,20) for each line number.
So, you essentially have something called a cartesian product here. For the data shown above, you have:

Iteration 1 => Outer: 1 - Inner: 10
Iteration 2 => Outer: 1 - Inner: 20

Iteration 3 => Outer: 2 - Inner: 10
Iteration 4 =>  Outer: 2 - Inner: 20

Now, assuming that you have found out a way to determine the line number, the two for loops would work as follows:

(Iteration 1) Put port no. 10 in line 1.
(Iteration 2) Put port no. 20 in line 1, thereby overwriting the port no. put in iteration (1).
(Iteration 3) Put port no. 10 in line 2.
(Iteration 4) Put port no. 20 in line 2, thereby overwriting the port no. put in iteration (3).

As you can see, this does not meet your stated goal of "replacing a specific string on a specific line number".

For this, you need a one-to-one relation between a line number and that specific string (which I assume is the port number).

Given below is a very simple file whose data shows such a relation:

$ 
$ cat output.2
2 222
5 555
6 666
7 777
$ 

So now, I want to put

  • the string "222" in line no. 2,
  • the string "555" in line 5,
  • the string "666" in line 6 and
  • the string "777" in line 7
    of the file, say, "output.clean".
$ 
$ cat output.clean
this is line 1
Destination port matches
this is line 3
this is line 4
Destination port matches
Destination port matches
Destination port matches
this is line 8
$ 
$ 

In fact, in such a case, you do not even need to search for "Destination port matches". That's because the substitution is based on the line number and not on a string match.

An awk program can be written for the same:

$ 
$ awk '{if (FILENAME=="output.2"){a[$1]=$2}else{if (a[FNR]==""){print $0}else{print "Dest port match",a[FNR]}}}' output.2 output.clean
this is line 1
Dest port match 222
this is line 3
this is line 4
Dest port match 555
Dest port match 666
Dest port match 777
this is line 8
$ 
$ 

You may want to brush up some concepts here.

  • FILENAME stores the name of the file being currently processed.
  • FNR is the record number of the current file.
  • The first if condition checks if the FILENAME is "output.2" and if so, it creates an associative array with the line number as the key and the port number as its value.
  • The else part goes to the "output.clean" file.
  • If the current line number of "output.clean" is not a key of the associative array (created earlier), then simply print the line.
  • Otherwise, print the string you want with the hash value in it.
  • Again, since the associative array must be created before "output.clean" is processed, the order of files has to be correct.

HTH,
tyler_durden

with the below i seem to get getting better results since the orig post

grep -v WARNING output | grep -v spawn | grep -v Passphrase | grep -v Authentication | grep -v '/sbin/tfadmin netguard -C'| grep -v 'NETWORK>' > output.clean
for x in `cat portlist` ; do
        sed 's/Destination Port matches/Desp port Match $x/' < output.clean >> output.final
done

my output is

Desp port Match $x
========================

but i cant seem to get the x var to print its value.... BTW i just couldnt follow your suggestion its been way too long since i did any of this and i wasnt event that good when i was doing it more often.

any thoughts on how to get the value of the var to print to the end of the line?

many thanks!