Odd behavior with grep -q in a bash script
I'm trying to write a small bash script that will check if each element of a sequence of numbers is in a given file, and print the ones that aren't.
find_missing.sh:
#!/bin/bash
for num in {1..5}; do
if ! [[ $(grep -q "$num" numbers.txt) ]]; then
echo "$num"
fi
done
numbers.txt:
1
2
5
Expected output:
3
4
Actual output:
1
2
3
4
5
If I change the line grep -q "$num" numbers.txt
to grep "$num" numbers.txt
, I get the expected output. However, my understanding is that the -q
flag should be returning an exit code of 0 if the number is found and an exit code of 1 if it isn't found, and I don't understand why having or not having the flag makes a difference.
If I try to run individual instances of the grep command, I get the behavior I expect:
grep -q "1" numbers.txt; echo "$?"
0
grep -q "3" numbers.txt; echo "$?"
1
Can anyone help me understand what's going on here?
Solution 1:
$( ... )
captures the output, but grep -q
produces no output. Don't use it. You don't even need the square brackets as if
can use the exit status:
if ! grep -q "$num" numbers.txt ; then
You can get the same output with
printf '%s\n' {1..5} | grep -vwFf numbers.txt -