0

If I have two files. File A looks like:

a 1
a 2
a 3
b 4
c 5

and I have file B which has content:

a
b

For everything that appears in file B and also appears in column 1 in file A, I would like to remove those lines. So the expected output for file A should be:

c 5

Any help is greatly appreciated!

Shirley Du
  • 45
  • 8
  • Write an awk script that creates an array whose keys are all the lines in file B. Then when it processes file A it prints the line if `$0 not in array`. – Barmar Sep 03 '16 at 00:24
  • 2
    Can other columns contain strings that are in file B? If not, you can use `grep -v -f fileB -w fileA`. – Barmar Sep 03 '16 at 00:25

2 Answers2

2

GNU Awk:

awk 'ARGIND == 1 { del[$0]++ } ARGIND == 2 && !del[$1]' B A

When processing the first file (ARGIND is 1), enter $0 (each entire line) into an associative array del by incrementing its entry.

When processing the second file, print if the first field $1 is not associated with a nonzero count in del.

Of course, we make B the first file and A second.

(The printing action is implicit when the ARGIND == 2 && !del[$1] pattern expression yields a Boolean true. A pattern without an action has an implict action equivalent to { print }).

ARGIND is not in POSIX. In portable Awk code, an ugly hack may be used to distinguish the first file from the second:

awk 'FNR == NR { del[$0]++ } FNR < NR && !del[$1]' B A

When the first file is processed, the "file record number" (record number in the current file) is equal to the "total record number" (absolute record number processed across all files). Of course, this breaks if the first file contains no records at all. See What is "NR==FNR" in awk?

Community
  • 1
  • 1
Kaz
  • 55,781
  • 9
  • 100
  • 149
0

The following will do the work,

awk 'FNR==NR{map[$1]=1;next;}map[$1]==""{print;}' <fileB> <fileA>
rakinhaider
  • 124
  • 7