0
#!/bin/bash

while echo -n "Player's name?"
    read name
    [ $name != 'ZZZ' ]
do
    searchresult=$(grep [$name] playername)
    if [ $searchresult = 0 ]
    then
        echo -n "if See target (T/t) or team name (M/m)?"
        while [ [ $target!="T" ] || [ $team!="M" ] ]

            read team
            read target

            do
                echo "Please enter only T or M."
            done
            if $target="T"
            then
                grep [ $name ] targetselected
            else
                grep [ $name ] teamselected
            fi

    else
        echo 'no such player'
    fi

done
echo You are now exited search

the runtime error saying

line 10 - if [ $searchresult = 0 ] ; have so many arguments,

what is that mean? how can i fix it?

1
  • You need to include samples of the three data files you're running grep on. You should also include a description of what you're attempting to do. Commented Feb 10, 2014 at 5:26

5 Answers 5

2

Quote the variable name:

"$searchresult"

Also, youa have other failures in the script.

  • remove brackets from the greps if you do not need them
  • rewrite the condition in while
Sign up to request clarification or add additional context in comments.

Comments

1

It would REALLY HELP if you include a sample of the data in the three files you're using 'grep' on!

You've misunderstood what the

variable=$(command)

operation does. The '$()' operation assigns the standard output of the command to the variable, not the exit code of the command. If you want to use your original script, with the exit code, try this instead:

grep [$name] playername > /dev/null 2>&1
searchresult=$?

The '=' operator in 'test' (also known as '[ ]') is for strings. You really want to use the '-eq' operator instead, which is for integers.

Without the data, I can't really figure out what the rest of the script should look like. As it is, it really looks strange to me.

Since you're using bash, I can make a suggestion for improving your input checking.

target=UnSeT
while [ $target = "UnSeT" ]
do
    read -p "if See target (T/t) or team name (M/m)?" target
    case "$target" in
        [Tt]) target="T";;
        [Mm]) target="M";;
        *) target="UnSeT"; echo "Please enter T or M.";;
    esac
done

Comments

1

Use -eq instead = in your if statement in your script or use -z option to check empty string.

4 Comments

My reading of tfm indicates that -eq, -ne, -ge et al are supposed to be used for arithmetic comparisons, not string comparisons, which is what the OP has in his script.
Yes you are right but my point is OP suppose not to compare string with 0.
In which case it should be either if [ $? -ne 0 ]; then ..... or if [ -z "$searchresult" ]; then ....
@james right, OP must follow your above suggestion for string operation.
1

There are multiple things wrong with your script. The most egregious problem is that you need to quote your variables.

For example, if $name contained a value with a space, you get weird results:

name='a value'
grep [$name] file

would end up grepping for [a (which isn't a valid regex) in value] (which almost certainly doesn't exist).

Quoting fixes that, but the use of [...] in grep is also weird. For example,

name='abc'
grep "[$name]" file

will find in file any line which contains a anywhere in it, or b anywhere in it, or c anywhere in it. This can hardly be what you want.

If your intention is to search for a literal string,

grep -F "$name" file

does that.

Here is an attempt to rewrite your script more idiomatically.

#!/bin/sh

while true; do
    read -p "Player's name? " name
    case $name in "ZZZ" | "") break ;; esac
    if grep -F -q "$name" playername; then
        # Not sure what the logic should be here?
        while true; do
            read -p "See target (T/t) or team name (M/m)? " choice
            case $choice in
                [Tt]) file=targetselected; break ;;
                [Mm]) file=teamselected; break ;;
            esac
            echo "Only enter T/t or M/m.  Try again."
        done
        grep -F "$name" "$file"
    else
        echo 'no such player'
    fi
done

There is nothing Bash-specific in this script, so I changed the shebang line to /bin/sh.

However, the logic seems awkward. I am imagining your players file would look something like this:

Maisy
Tallulah
Cyril
Eddie

and the teams something like

Tallulah,Chickens,Astronauts
Maisy,Obnoxity,Fallacious
Cyril,Rodents
Eddie,Dirt,False,Breakfast of Champions

then if you search for "all" you would find "Tallulah" in the first file, but print both Maisy and Tallulah from the teams file because they both contain the text "all" somewhere on the line. It would be better to simply search the team or target file directly, perhaps using Awk instead of grep:

awk -F, -v q="$1" '$1 ~ q' "$file"

and if there was no output, the player didn't exist in the first place.

As you grow more familiar with the Unix shell, you will want to avoid tools which force an interactive dialog. Instead, you might want to have a simple tool like this:

#!/bin/sh
file=players
while true; do
    case $1 in
        -[Tt]) shift; file=targetselected;;
        -[Mm]) shift; file=teamselected;;
        *) break;;
    esac
done
awk -F, -v q="$1" '$1 ~ q' "$file"

which is easy to use as a component in a larger script, easy to recall from your command history, easy to add not one but many different GUIs around if you really need one, and (once you get used to it) easy to use.

Comments

0

grep returns multiple words so shell interprets the if statement as having so many tokens. If you just want to check if there was a match, do this:

if grep "$name" playername &> /dev/null; then
    # ....

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.