Home > front end >  Trying to do script to search user input in a file
Trying to do script to search user input in a file

Time:03-22

I am trying to learn Bash scripting, and doing some excercises.

Right now trying to create script that search names and fetch records from a file. The file content is like that: Name:Phone:Email Example: John Doe:123456789:[email protected] However I have created a function

names=$(awk '{print $1}' $HOME/name_list.txt)

name_list()
{
for i in $names; do
    if [ "$i" == "$name" ];then  #name is user input from scriptfile.
        echo $names | grep -o $i | wc -l | tr "\n" " ";echo "person found" 
    else
        echo "Couldn't find anyone with given name"
    fi
done
}

What I', troubled with, my if condition generates "person found" output for every 'i' in the file. Likewise the else condition generates output for every 'i' that not matches. I can understand why it's working like that but I couldn't find a way to do that otherwise. I want my script to scan all files and generates only 1 output for total matches and only 1 output for if there are no matches.

CodePudding user response:

If you are using Awk anyway, it makes sense to implement all of your logic in Awk.

awk -v name="$1" -F : '$1 == name {   found }
  END { if (found) printf "Found %i instances of %s\n", found, name
     else printf "Not found: %s\n", name }' "$HOME/name_list.txt"

CodePudding user response:

Assuming that name_list.txt is as-advertised (just a list of names), then you should be able read grep's search strings from a file with...

echo $names | grep --file=$HOME/name_list.txt # ...

I should mention that grep also provides -c or --count, which counts the matches. Using a modern style of grep, you'll also want to know about -w or --word-regexp, which will refuse to match target patterns if they don't represent a full word (or set of words) in the source, so that "John" won't match "Johnson."

That'll require reorganizing your script, since grep does most of the work, and might violate the terms of the exercise that you actually want to do, of course. In that case, you might want to write the line-by-line results to a temporary file, then add them up for the output.

CodePudding user response:

Assuming you only want to show "not found" message once..... You can try something like this:

names=$(awk -F'[:]' '{print $1}' name_list.txt)
IFS=$'\n'
name=$1
found=0

name_list(){
for i in $names; do
    if [ "$i" == "$name" ];then  #name is user input from scriptfile.
      echo "person found at line $(grep -n $name name_list.txt | cut -d: -f1)"
      found=1
      break
    fi
done

if [ $found == 0 ]
then
    echo "Couldn't find anyone with given name"
fi
}

I only added -F'[:]' in AWS line IFS=$'\n'.

  • Related