elwayisgod
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
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
grep "Denver$" yourfile
You "can't use awk". Warning! Warning! Homework question.
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
#!/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 ;-)
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 ;-)
ASKER
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
#!/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.
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.
ASKER
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/reg is/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/reg is/project 74 %
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/reg
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/reg
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Shouldnt this sort correctly. When I run and choose to sort by option 3, I get:
SMITH,BRAD,STL,DEN,147,DEL AYED,05/11 /2004
SMITH,ROD,DEN,LAX,214,ONTI ME,08/21/2 004
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
SMITH,BRAD,STL,DEN,147,DEL
SMITH,ROD,DEN,LAX,214,ONTI
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
ASKER
Nevermind, used the -t, option as it was comma delimited..
sam
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.
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
#!/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