4

I need as short as possible bash test command (bracket test) to evaluate result of piped grep with variable as search argument. I am testing, whether a new string is in the array - piping the array contents as lines to grep and checking exit code. But it somehow does not work. Does not find the value in the array. I have tried in various ways brackets, parenthesis, quotes, semicolons with no luck. What is wrong here?

#! /bin/bash
startLineNrs=();
startLineNrs+=("45");
startLineNrs+=("280");
startLineNrs+=("80");
startLineNr="280";
echo "\$startLineNrs:" ${#startLineNrs[@]};
printf '%s\n' "${startLineNrs[@]}";
[ "$(printf '%s\n' ${startLineNrs[@]} | grep -xq ${startLineNr})" ] && { echo $?; echo Found ;} || { echo $?; echo Not found ;}

Basically I want to understand the if...then construct versus the brackets test. The if...then method works:

if !( printf '%s\n' "${startLineNrs[@]}" | grep -xq "${startLineNr}" ); then startLineNrs+=("$startLineNr") ; fi
uldics
  • 67

2 Answers2

3

The correct way to write your if statement is:

if printf '%s\n' "${startLineNrs[@]}" | grep -xq "$startLineNr"; then
  # your logic
fi

The issue with your test statement [...] is that [ or test treats "$(printf '%s\n' ${startLineNrs[@]} | grep -xq ${startLineNr}) as a string, and it doesn't run it as a command substitution. Since it is a non-empty string, it will always evaluate to true.

codeforester
  • 164
  • 1
  • 1
  • 8
3

To make the &&--|| command work, try:

printf '%s\n' ${startLineNrs[@]} | grep -xq ${startLineNr}  && { echo $?; echo Found ;} || { echo $?; echo Not found ;}

Notes:

  1. The test command ([) and the command substitution ($(...)) are not needed.

  2. A subtlety of the construct a && b || c is that c will be executed not just if a fails but also if b fails. Since your b consists of echo statements which should normally succeed, this should not normally be a problem.

  3. For other methods for testing array membership, see "Check if a Bash array contains a value".

John1024
  • 17,343