Michal Kordas
Michal Kordas

Reputation: 10925

Filter lines with the other set of lines in Bash

I have lines on my standard input

$printf "C\nB\nA\n"
C
B
A

and I want to filter out lines (or substrings or regexps - whatever is easier) that appear on some other standard input:

$printf "B\nA\n"
B
A

I expect just C when entries get filtered.

I've tried with

$printf "C\nB\nA\n" | grep -v `printf "B\nA\n"`

But then I'm getting

grep: A: No such file or directory

How can I perform filtering of standard input by lines returned by other command?

Upvotes: 4

Views: 3751

Answers (3)

Roberto Bonvallet
Roberto Bonvallet

Reputation: 33319

You can use grep's -f option:

Matching Control
    -f FILE, --file=FILE
          Obtain patterns from FILE, one per line.
          [...]

and use the <(command) syntax for using a command's output as the content to be used:

$ printf "C\nB\nA\nA\nC\nB" | grep -vf <(printf "A\nB\n")
C
C

Upvotes: 7

maco1717
maco1717

Reputation: 843

U can use

printf "C\nB\nA\n" | grep -v C

and subsequently

printf "C\nB\nA\n" | grep -v C | grep -v B

then

printf "C\nB\nA\n" | grep -v A | grep -v B

if you want to do it from a file assuming file contains

C
B
A

then:

cat file | grep -v B | grep -v A

will print

C

if you want to filter by only piping once

cat file | grep -v 'B\|A'
C

Upvotes: 0

Andreas Louv
Andreas Louv

Reputation: 47099

Use awk to get control of how each line should match each other:

$ printf "C\nB\nA\n" | awk 'NF == FNR { a[$0] = 1; next } a[$0]' \
  <(printf "A\nB\n") - 

By changing a[$0] you can define how each should match, i.e to print lines from file1.txt which first column are in file2.txt:

$ awk 'NF == FNR { a[$0] = 1; next } a[$1]' file2.txt file1.txt
#                                      ^ Print if column 1 from file1.txt
#                                        is in file2.txt

To print lines from file1.txt which are contained in column one from file2.txt:

$ awk 'NF == FNR { a[$1] = 1; next } a[$0]' file2.txt file1.txt
#                                      ^ Print if line from file1.txt match
#                    ^ Store column one from file2.txt

Upvotes: 2

Related Questions