Script that takes IP address as an Input and deletes 7 lines

I have a flat file that contains a list of IP address following 6 additional lines.

I would like to get a help in the following. a shell script that would take ip address or list of ip addresses as input, search one by one the ip address in the file and as soon as it find the exact match it deletes 7 lines including the line that has the ip address. it should then save the file

for example lets say we want to find 166.1.1.3 , the script should be able to find 166.1.1.3 and delete 7 lines including 166.1.1.3.

File contents shown below

166.1.1.1
Line1
Line2
Line3
Line4
Line5
Line6

166.1.1.2
Line1
Line2
Line3
Line4
Line5
Line6

166.1.1.3
Line1
Line2
Line3
Line4
Line5
Line6

166.1.1.33
Line1
Line2
Line3
Line4
Line5
Line6

Here is an awk approach:

awk '
        NR == FNR {
                I[$1]
                next
        }
        $1 in I {
                F = 1
                next
        }
        F && ++c == 7 {
                F = 0
                c = 0
                next
        }
        !(F)
' ipfile infile

or:

awk 'FNR==NR{ip[$0];next} !($1 in ip)' ipFile RS= ORS='\n\n' inputFile

Yoda's code optimized

awk '
(NR == FNR) {
 A[$1]
 next
}
($1 in A) {
 c = 8
}
!(c && c--)
' ipfile infile

---------- Post updated at 02:34 AM ---------- Previous update was at 01:39 AM ----------

If output on terminal looks good you can overwrite the input as follows

infile=./infile
cp -p $infile $infile.old &&
awk '
(NR == FNR) {
 A[$1]
 next
}
($1 in A) {
 c = 8
}
!(c && c--)
' ipfile $infile.old > $infile

I tried to set up the script and I am getting teh following error !!!
more script_IPRemove.sh

#!/usr/bin/ksh -x
infile=./infile
/usr/bin/cp -p $infile $infile.old &&
/usr/bin/awk ' (NR == FNR) { A[$1] next } ($1 in A) { c = 8 } !(c && c--) ' $ipfile $infile.old > $infile

Error that I am getting
--------------------------

script_IPRemove.sh 1xx.3x.5x.1x
+ infile=./infile
+ /usr/bin/cp -p ./infile ./infile.old
+ /usr/bin/awk  (NR == FNR) { A[$1] next } ($1 in A) { c = 8 } !(c && c--)  ./infile.old
+ 1> ./infile
awk: syntax error near line 1
awk: illegal statement near line 1
awk: syntax error near line 1
awk: bailing out near line 1
  1. There must be a semicolon between statements within a block (if not on separate lines).
  2. In Solaris you better use /usr/xpg4/bin/awk or nawk.
    Best practice is to define PATH at the beginning of the script .
  3. $ipfile is yet undefined. (You could pass script parameter instead.)
PATH=/usr/xpg4/bin/:/bin:/usr/bin:/usr/sbin
export PATH
infile=./infile
cp -p $infile $infile.old &&
awk ' (NR == FNR) { A[$1]; next } ($1 in A) { c = 8 } !(c && c--) ' "$ipfile" $infile.old > $infile

First off, an observation: if you want to delete the line containing the IP address and the next 6 lines you will accumulate empty lines. In your input sample there are always 7 lines in a block separated by a single blank line. If you want to preserve this structure you'd have to delete 8 lines, not seven.

Second, the probably easiest way to do this is "sed":

#!/bin/ksh

typeset search=""
typeset fIn="./7lines.in"
typeset fTmp="./7lines.tmp"

while [ -n "$1" ] ; do
     search="$1"
     shift
     sed '/^'"$search"'[^0-9]*/,+6 d' "$fIn" > "$fTmp"
     mv "$fTmp" "$fIn"
done
exit 0

You may notice that the script lacks seriously in checks: checks for enough disk space, free inodes to create files, write privileges, successful operation of sed, sanity checks for the command line arguments, ... These are left as an exercise for the avid reader.

If you want to go for eight instead of seven lines in light of what i wrote above, change the "+6" to "+7" in the sed-script above.

I hope this helps.

bakunin

Let me please reiterate my issue, From the Input file, I need to search for an exact Match of the IP address, for example If I search for 111.46.14.10, it should only find 111.46.14.10 IP address not 111.46.14.101, once it finds the IP address (Exact Match) then it should delete the Line that contains the IP address and the next 7 lines (there are always going to be two blank lines). So all together 8 lines should be deleted

Lets say we are searching for 111.46.14.10 from the Input file below the Output file should look like

Here is the Input File
--------------------

# 111.46.14.98

Line1
Line2
Line3
Line4
Line5

# 111.46.14.99

Line1
Line2
Line3
Line4
Line5

# 111.46.14.100

Line1
Line2
Line3
Line4
Line5

# 111.46.14.10

Line1
Line2
Line3
Line4
Line5

# 111.46.14.101

Line1
Line2
Line3
Line4
Line5

# 111.46.14.102

Line1
Line2
Line3
Line4
Line5

# 111.46.14.103

Line1
Line2
Line3
Line4
Line5

# 111.46.14.104

Line1
Line2
Line3
Line4
Line5

# 111.46.14.105

Line1
Line2
Line3
Line4
Line5

# 111.46.14.106

Line1
Line2
Line3
Line4
Line5

# 111.46.14.107

Line1
Line2
Line3
Line4
Line5

# 111.46.14.108

Line1
Line2
Line3
Line4
Line5

Expected Output File Should look like below
-----------------------------------------

Here is the Input File
--------------------

# 111.46.14.98

Line1
Line2
Line3
Line4
Line5

# 111.46.14.99

Line1
Line2
Line3
Line4
Line5

# 111.46.14.100

Line1
Line2
Line3
Line4
Line5

# 111.46.14.101

Line1
Line2
Line3
Line4
Line5

# 111.46.14.102

Line1
Line2
Line3
Line4
Line5

# 111.46.14.103

Line1
Line2
Line3
Line4
Line5

# 111.46.14.104

Line1
Line2
Line3
Line4
Line5

# 111.46.14.105

Line1
Line2
Line3
Line4
Line5

# 111.46.14.106

Line1
Line2
Line3
Line4
Line5

# 111.46.14.107

Line1
Line2
Line3
Line4
Line5

# 111.46.14.108

Line1
Line2
Line3
Line4
Line5

That's a new format/requirement.
# 111.46.14.108 is not an IP address. I.e. 111.46.14.108 does not exactly match.

---------- Post updated at 01:27 PM ---------- Previous update was at 01:19 PM ----------

awk ' (NR == FNR) { A[$0]; next } ($0 in A) { c = 8 } !(c && c--) ' ipfile infile

(i.e. $0 instead of $1) takes full lines.
In your last example ipfile must have # 111.46.14.10 that must exactly be in the infile.

ipfile will only have ip address nothing else

For example

111.46.14.10
111.46.14.101
111.46.14.102

the script should take these as the input and then look for each ip address in teh infile and then remove the line it out the ip address and the next 7 lines, when I say remove I mean delete the following 7 lines

Try this:

awk 'NR==FNR {T[$1];next} $2 in T {LN=NR+7} NR>LN' file1 file2

Thank you

/usr/xpg4/bin/awk ' (NR == FNR) { A[$0]; next } ($0 in A) { c = 7 } !(c && c--) ' "$ipfile" $infile.old > $infile

This one worked !!!

Can we use this code to search alpha numeric strings as well? instead of IP addresses

If the ipfile contains the following contents


80:00:1f:0e:03:c0:d7:21:50:20:bf
81:00:1f:02:e3:c0:d7:21:50:20:be

Can I use the code below to search the strings above by using the command below.

/usr/xpg4/bin/awk ' (NR == FNR) { A[$0]; next } ($0 in A) { c = 7 } !(c && c--) ' "$ipfile" $infile.old > $infile

---------- Post updated at 04:40 PM ---------- Previous update was at 12:13 PM ----------

The following code did work !!!

/usr/bin/nawk "/$pattern/ {c=4} c && c-- {next}1" $infile.old > $infile