what is wrong with my unix script

后端 未结 5 1020
温柔的废话
温柔的废话 2021-01-29 03:17
#!/bin/bash

while echo -n \"Player\'s name?\"
    read name
    [ $name != \'ZZZ\' ]
do
    searchresult=$(grep [$name] playername)
    if [ $searchresult = 0 ]
    the         


        
5条回答
  •  后悔当初
    2021-01-29 03:42

    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.

提交回复
热议问题