0

I'm trying to write a simple script that if a line has 7 commas in it, either true or false will be returned. But I'm running into a couple of errors. The first error is coming from the grep, if I remove the -o, I still receive the error. And I'm not sure why 0 is being displayed and why it's returning as false? I'm also having trouble with equal; as in neither -eq or == is working.

Script:

#!/bin/bash
str="a,g,5,d,s,c,f,s"
stat=grep -o "," <<< "$str" | wc -l
if [ $stat == '7' ];then
        echo "true"
else
        echo "false"
fi

Here is the output I'm receiving:

./tesh.sh
./tesh.sh: line 3: -0: command not found
0
./tesh.sh: line 4: [: ==: unary operator expected
false
BB956
  • 31
  • 3
  • 11
  • 1
    http://shellcheck.net/ is your friend. Lots of separate small bugs here, no individual bug to make a good SO question. – Charles Duffy Jul 17 '18 at 15:49
  • 1
    Possible duplicate of [How to set a variable to the output of a command in Bash?](https://stackoverflow.com/q/4651437/608639), [How to store a command in a variable in Linux?](https://stackoverflow.com/q/5615717/608639), etc. – jww Jul 17 '18 at 15:57

2 Answers2

0

Correct the below line in your script.

stat=$(grep -o "," <<< "$str" | wc -l)

Also correct you if condition like below as you are comparing with a numeric value

if [[ $stat -eq 7 ]];then
Abhijit Pritam Dutta
  • 5,521
  • 2
  • 11
  • 17
0

Several issues here.

  • var=value somecommand arg1 arg2 ... exports var in the environment in the context where somecommand is executed (without changing the environment for any future commands); it doesn't set key to the output of somecommand.

  • [ $stat == '7' ] has multiple distinct issues:

    • [ doesn't guarantee that == is a supported operation at all. The POSIX test specification guarantees that = will be available for string comparisons, or -eq for numeric ones. ([[ does guarantee support for ==, and avoid the need for quotes; its use also explicitly disclaims portability to baseline /bin/sh implementations).
    • $stat, unquoted, can expand to an unknown number of words, depending on the current value of IFS and the contents of the variable. This means that if your wc command failed for some reason, you can end up running [ = 7 ] -- which yields your "unary operator unexpected" error -- not [ "" = 7 ], which is correctly false. By contrast, the 7 doesn't need to be quoted -- it can't possibly expand to anything other than itself.

Instead of counting the number of commas, read your comma-separated items into an array, and count the number of array members. This can be done using only tools built into the shell itself, as documented in BashFAQ #1 -- thus, with none of the (substantial) overhead of starting external executables such as wc or grep:

IFS=, read -r -a pieces <<<"$str"
if (( ${#pieces[@]} == 8 )); then
  echo "Correct number of pieces found"
else
  echo "Error: Only ${#pieces[@]} pieces found in line"
fi

This lets you refer to the items individually:

echo "This first piece is ${pieces[0]}"
echo "The last piece is ${pieces[7]}"
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441