I want to know on which ports of firewalls from a particular customer the MAC Address Filtering is not active. So I have created 2 files:

  • all.txt contains a list of all firewalls of a customer and looks like this:
  • active.txt contains a list of firewalls of the same customer in which the MAC Address filtering is active, and looks like this:
    abc123: set macaddr 00:00:00:00:00:00
    ahg578: set macaddr 00:00:00:00:00:00
    dfh879: set macaddr 00:00:00:00:00:00
    ert258: set macaddr 00:00:00:00:00:00
    fgh123: set macaddr 00:00:00:00:00:00
    huz546: set macaddr 00:00:00:00:00:00
    mnh323: set macaddr 00:00:00:00:00:00
    xsd451: set macaddr 00:00:00:00:00:00
    wqa512: set macaddr 00:00:00:00:00:00
    zas423: set macaddr 00:00:00:00:00:00

I have compared the two lists using

comm -3 ~/active.txt ~/all.txt

and get this result:


How can I get only the unmatched list as an output? So I want the output to be only


I have tried using sdiff, grep -rL, grep -vxFf but none of them works.

FYI, I'm using GNU. Linux version 3.2.0-6-amd64; gcc version 4.9.2

I would really appreciate your help! Thank you! :)


2 Answers 2


grep -v will work, just swap source with target. - will use pipe for -f
instead -x whole line -w whole word is recommended to ignore whitespaces from all.txt

cut -d\  -f1 active.txt | grep -vxFf - all.txt

Note the two whitespaces for cut: one escaped whitespace as delimiter

edit: if delimiter is a colon one must cut at : instead

cut -d: -f1 active.txt | grep -vwFf - all.txt

You can do it with awk. The challenge in this case is that in active.txt the ports are immediately followed by a :, whereas in all.txt they stand isolated on the line. So you need to change the field separator in between:

awk -F':' 'FS==":"{ports[$1];next} !($1 in ports)' active.txt FS=" " all.txt

This will use the : as field separator while reading the list of active ports (i.e. processing the first file, active.txt), but set it to a space for processing the next file, all.txt.

  • While processing active.txt (indicated by FS, the field separator, being equal to : as set via the -F option), we simply register the ports (i.e. the part before the first :) in an array ports. Execution then immediately skips to the next input line.
  • While processing all.txt (FS is now a space, so the first action block is never entered), we simply check if the port is registered in the array ports. If it is not, the condition will evaluate to true, and the default action print will be invoked.
  • It works!!! Thank you so much @AdminBee :) You're a hero!! :)
    – Ella Widya
    Aug 26, 2021 at 11:42
  • @EllaWidya You're welcome ;)
    – AdminBee
    Aug 26, 2021 at 11:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .