Link to home
Start Free TrialLog in
Avatar of elwayisgod
elwayisgodFlag for United States of America

asked on

Search a specific field in a table

Hi,

I'm trying to use grep to searh for a string in a table. However I need to limit the search to a specific field as I dont want any results from the first field if it contains the string.  Then I need to print a few of the fields from the lines that contain my string in the field I need to search on.  Here's an example of my data:

Toteve     Sam      Denver
Denver     John     Aspen
Ellis          Joe       Witchita
Toms       Mary     Denver

I want to search column 3 for Denver, but not pick up the John Denver line as I'm only searching column 3.  It's easy in awk, but I cant use awk... Do I use Grep....I dont see how I can use Grep.

Thanks,

Sam
Avatar of tfewster
tfewster
Flag of United Kingdom of Great Britain and Northern Ireland image

grep "Denver$" yourfile
Avatar of Tintin
Tintin

You "can't use awk".  Warning!  Warning!  Homework question.

Avatar of elwayisgod

ASKER

Why does this not work?

#!/usr/bin/ksh

# Search by Name

echo "What Last Name do you want to search for: \n"
read lname


nawk -F"," '$1 == /$lname/ { print }' flight.data
awk doesn't accept global parameter substitution in that way; You have pass parameters from the awk command line, e.g. nawk -F"," '$1 == NAME { print }' -v NAME=$lname flight.data

It occurred to me that you might be using grep because you didn't know how to do case-insensitive comparisons in awk; The answer to that is, use IGNORECASE, e.g.
lname=denVer
nawk -F"," 'BEGIN {IGNORECASE=1} $1 == NAME { print }' -v NAME=$lname flight.data

(P.S. Tintin - I agree it looks odd, but checking the profile reassured me ;-)
Not sure about the -v option.  I think I can do the NAME=$lname before the print statement. However, can't figure out the -v. Here is my current script.  If i leave the -v out, it does not print the lines where 'Toteve' is present. It is just blank output.


#!/usr/bin/ksh

# Search by Name

echo "What Last Name do you want to search for: \n"
read lname
echo $lname
NAME=$lname

nawk -F"," '$1 == NAME { print }' -v flight.data
Did you try it the way I suggested?  
nawk -F"," '$1 == MYAWKVAR { print }' -v MYAWKVAR=$lname flight.data

If you don't do the assignment on the awk command line, MYAWKVAR is undefined within awk, even it it's a global variable. You're using Solaris, aren't you?  Check the -v option in the man page for nawk.  
Here is my script and the results of output when I do it the way you indicated.  It thinks -v is a file, thus errors out...



SCRIPT:
#!/usr/bin/ksh

# Search by Name

echo "What Last Name do you want to search for: \n"
read lname
echo $lname
NAME=$lname
echo $NAME

nawk -F"," '$ 1== NAME { print }' -v NAME=$lname flight.data

OUTPUT:

broncos:/Users/stoteve/regis/project 73 % ./name.ksh
What Last Name do you want to search for:

Toteve
Toteve
Toteve
nawk: can't open file -v
 source line number 1
broncos:/Users/stoteve/regis/project 74 %
ASKER CERTIFIED SOLUTION
Avatar of tfewster
tfewster
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Shouldnt this sort correctly.  When I run and choose to sort by option 3, I get:

SMITH,BRAD,STL,DEN,147,DELAYED,05/11/2004
SMITH,ROD,DEN,LAX,214,ONTIME,08/21/2004

Why is DEN line not above the STL line?

#!/usr/bin/ksh

# Search by Name

cat flight.data | tr [a-z] [A-Z] > flight.data #Change data file to UPPERCASE

echo "What Last Name do you want to search for: \n"
read lname


echo "$lname" | tr [a-z] [A-Z] > lnametr
cat lnametr
NAME=`cat lnametr`

echo "What field would you like to sort your results by: \n\n
      1) Last Name \n
      2) First Name \n
      3) Departure City \n
      4) Arrival City \n
      5) Flight Number \n
      6) Departure Date \n"


read srtfld

#cat newflight.data

case "$srtfld" in
      
      1)cat newflight.data | sort +0 newflight.data
            ;;
      2)cat newflight.data | sort +1 newflight.data
            ;;
      3)cat newflight.data | sort +2 newflight.data  
            ;;
      4)cat newflight.data | sort +3 newflight.data
            ;;
      5)cat newflight.data | sort +4 newflight.data
            ;;
      6)cat newflight.data | sort +6 newflight.data
            ;;
      *) echo "Invalid Option.  Sorting by default 'Last Name' \n"
             cat newflight.data | sort +0 newflight.data
            ;;
            
esac



# Line 47
nawk -F"," -v NAME=`cat lnametr` '$ 1== NAME { print }'  flight.data > newflight.data
#cat newflight.data | sort +$srtfld newflight.data
Nevermind, used the -t, option as it was comma delimited..

sam
Hmmm - That has nothing to do with the awk/grep questions and it's a bit unreasonable. Please see https://www.experts-exchange.com/Operating_Systems/Unix/help.jsp#hi107

However, you need to specify the delimiter character to `sort` using the -t option;  As it is, it sees each line as a single field, and this cannot sort on "field 3".

Furthermore, `cat newflight.data | sort +6 newflight.data` is redundant;  Just do `sort -t, +6 newflight.data`

Finally, newflight.data doesn't get created until the end of the script "#Line 47", so the case statement must be working on old data.  
grep is still suitable (and easier)

#!/usr/bin/ksh
echo "What Last Name do you want to search for: \c"
read lname

grep "^$lname" flight.data

For your sorting script, it would be better written as:

#!/usr/bin/ksh

echo "What Last Name do you want to search for: \c"
read lname

cat <<EOF
What field would you like to sort your results by:

     1) Last Name
     2) First Name
     3) Departure City
     4) Arrival City
     5) Flight Number
     6) Departure Date

EOF

echo "Enter option: \c"
read srtfld

case "$srtfld" in
1) sort -t, +0 newflight.data ;;
2) sort -t, +1 newflight.data ;;
3) sort -t, +2 newflight.data ;;
4) sort -t, +3 newflight.data ;;
5) sort -t, +4 newflight.data ;;
6) sort -t, +6 newflight.data ;;
*) echo "Invalid Option.  Sorting by default 'Last Name'"
   sort -t +0 flight.data
   ;;
esac

grep -i "^$lname" newflight.data