Reputation: 10925
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
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
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
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