2

I need help to parse an input like this.

192.168.0.168: 1
192.168.0.158: 0
192.168.0.198: 0
192.168.0.148: 0
192.168.0.158: 1
192.168.0.168: 0

If there is 1 in second column of any ip, I want to delete the row which have 0 in second column and same ip in first column. So my output should be like this.

192.168.0.168: 1
192.168.0.198: 0
192.168.0.148: 0
192.168.0.158: 1

I guess It can be done by using awk, sed etc. but I have no idea how to do that. I hope I could explain my question correctly. Thanks...

6 Answers 6

2

One way:

awk '
    { 
        ips[ $1 ] = ( ips[ $1 ] == 1 ) ? 1 : $2 
    } 
    END { 
        for ( ip in ips ) { 
            print ip, ips[ ip ] 
        } 
    }
' infile

That yields (output could be unordered):

192.168.0.168: 1
192.168.0.198: 0
192.168.0.148: 0
192.168.0.158: 1
Sign up to request clarification or add additional context in comments.

Comments

2

This might work for you (GNU sed):

cat -n file | 
sort -k2,2 -k3,3nr | 
sed ':a;$!N;/^\s*\S*\s*\(\S*\)\s*1\s*\n.*\1/s/\n.*0\s*//;ta;P;D' | 
sort -n | 
sed 's/^\s*\S*\s*//'

Comments

1

Perl solution:

perl -nae '$h{ $F[0] } += $F[1]
           }{
           print "$k ", $v ? 1 : 0, "\n" while ($k, $v) = each %h'

Comments

1

A couple of sorts should do:

sort file -r | sort -u -k1,1

The former sort makes sure the lines are ordered so that lines with 1 on the second column will come first for every IP.

The latter sort will keep only the first entry for each IP: -u -> unique, -k1,1 -> first column only.

1 Comment

To preserve line order you can use same trick that potong's answer uses. First number the lines and with cat -n, and post sort on first column: cat -n infile | sort -k2 -r | sort -u -k2,2 | sort -n | cut -f2-.
1
awk '{a[$1]+=$2}END{for(i in a)print i,a[i]}' your_file

Comments

1

Functional approach (haskell programming language):

-- function that having the two sublists with '0' and '1' ips,
-- filters and puts into   the '1' 
-- sublist all the '0' ips that are not included in '1'

fil [] result = result
fil (x: xs) result | (init x `elem` (map init result)) == False = fil xs (x:result)
            | otherwise = fil xs result


-- function that filters '0' and '1' sublists
getsublist alist character = filter (\x-> (last x) == character) alist



> let a = ["192.168.0.168: 1", "192.168.0.158: 0", "192.168.0.198: 0", "192.168.0.148: 0", "192.168.0.158: 1", "192.168.0.168: 0"]

> let b = getsublist a '0'

> let c = getsublist a '1'

> fil b c

Output:

["192.168.0.148: 0","192.168.0.198: 0","192.168.0.168: 1","192.168.0.158: 1"] 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.