1

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?

1
  • $( ... ) captures the output, but grep -q produces no output. Commented Jul 27, 2021 at 15:34

1 Answer 1

2

$( ... ) 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 - 
2
  • What exactly is the final - signifying in your alternate construction? Commented Jul 27, 2021 at 15:52
  • 1
    @NathanPierson The - tells grep to search its standard input (in this case, the input from the pipe). See #13 in the POSIX utility syntax guidelines. Note that the numbers.txt file is not what's being searched, it's an argument to the -f option, meaning that its contents will be used as a list of things to search for (or rather, search for the absence of, because the -v option inverts the search). Commented Jul 27, 2021 at 21:52

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.