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'.