Issue
I have an array
arr=( 'error one' 'error two' 'error three' )
and a file I want to find errors in
a.txt
with contents (example).
error one
error two
error three
error four
error five
error six
error seven
eight
nine
ten
When I run my script I want to ignore all errors I have already found (the errors in the array) and find new ones.
So far I have this
arr=( 'error one' 'error two' 'error three' )
grep -v 'error one\|error two\|error three' a.txt | grep error
which returns this (correct).
error four
error five
error six
error seven
The contents of the array will change over time though, based on more errors I find, or errors I stop finding, and I would prefer to instead reference the array as a whole rather than list each item.
So far I have something like this.
arr=( 'error one' 'error two' 'error three' )
function join_by { local d=$1; shift; echo -n "$1"; shift; printf "%s" "${@/#/$d}"; }
list=$(join_by "\|" "${arr[@]}")
echo ${list}
grep -v ${list} a.txt | grep error
Of course this doesn't work, but I don't know how to proceed from here, or whether to change the method entirely.
Any help would be appreciated.
Solution
You don't have to join patterns by \|
, grep accepts a newline separated list as well. So you can simply do:
grep -v "$(printf '%s\n' "${arr[@]}")" a.txt | grep error
Proof of concept:
$ arr=(2 4)
$ seq 4 | grep -v "$(printf '%s\n' "${arr[@]}")"
1
3
Answered By - oguz ismail