views:

617

answers:

5

I have a file which has 50 rows. Each row is made up of three columns. The first two columns are the variables and this will be passed as parameters to return the 3rd column's value. for ex.. command_file.txt is the file and it contains

A B 10
C D 20
E F 30
G H 50
I J 70
...

I have a script with the following command.

#!/user/bin/sh
READ_FILE=/export/home/user/command_file.txt
VA1=A
VA2=B
GET_VALUE=`awk '/ -v var="$VA1" '$1 ~ var' -v var1="$VA2" '$1 ~ var1''/ $READ_FILE l awk '{print $3}'`
echo $GET_VALUE

When I call this script passing A and B as parameters I expect a value of 10 to be returned.But it returned errors. But if I hard code the value on the below command it will work.

GET_VALUE=`awk '/A B'/ $READ_FILE lawk '{print $3}'`

Any suggestions? Thanks.

+1  A: 

I apologize that I can't really determine what your script is trying to do, so I can't debug it properly. I think maybe you have nested quotes or something else is going on.

I think the one-liner below will do what you want.

#!/bin/bash
grep "^$1 $2" /export/home/user/command_file.txt | awk '{print $3}'

Edit

Okay thanks to others for pointing out what you were trying to do with the -v options.

Your code is missing a $ on the echo GET_VALUE command, and you have a letter l instead of a pipe |. Plus there are other typos as well.

I think this works

READ_FILE=/export/home/user/command_file.txt
awk -v var1=$1 -v var2=$2 '$1 ~ var1 && $2 ~ var2; /^var1 var2/' $READ_FILE | awk '{print $3}'

but I prefer the grep command above as it requires no extra effort to pass the command line variables to awk.

bmb
The `/^var1 var2/` is redundant and the ";" makes the matches before it print every input line (since there's no action before the semicolon).
Dennis Williamson
Also, piping it into awk a second time is unnecessary. It can print the field while it's got it the first time.
Dennis Williamson
Dennis Williamson, thanks. Good catches. I probably should have just stuck with my original with grep. I think that's the better way to go anyway.
bmb
A: 

Or perhaps:

#!/bin/bash
grep "$1" test.txt | grep "$2" | awk '{print $3}'

If your vars need to be in either order?

toolkit
`$1` and `$2` are awk fields in this context, not positional parameters. The pertinent variables are `$VA1` and `$VA2`.
Dennis Williamson
+1  A: 

You have to use awk's variable passing before the awk script begins to avoid hairy quoting, plus fix other problems:

#!/user/bin/sh
READ_FILE=/export/home/user/command_file.txt
VA1=A
VA2=B
GET_VALUE=$(awk -v var="$VA1" -v var1="$VA2" '$1 ~ var &&  $2 ~ var1 {print $3}' $READ_FILE)
echo $GET_VALUE
Dennis Williamson
Note this still has the OP's typo with the missing $ on the echo command.
bmb
I have now fixed mine and the OP's. Thanks for the pointer.
Dennis Williamson
+1  A: 

I think this is what you're looking for:

#!/user/bin/sh
READ_FILE=/export/home/user/command_file.txt
VA1=A
VA2=B
GET_VALUE=`awk -v var1=$VA1 -v var2=$VA2 '$1==var1 && $2==var2 {print $3}' command_file.txt `
echo $GET_VALUE
dj_segfault
This one probably won't work.
Dennis Williamson
A: 

Fixed:

#!/user/bin/sh
READ_FILE=/export/home/user/command_file.txt
VA1=A
VA2=B
GET_VALUE=`awk "/$VA1 $VA2/ "'{print $3}' < $READ_FILE`
echo $GET_VALUE
rosenfield
It's better to pass in the variables with `-v` rather than play tricks with quoting.
glenn jackman
@glenn: huh? define "better"? it sure aint prettier
rosenfield
@rosenfield: It's not necessary to redirect the input file; awk accepts filenames as arguments. Also, getting the quoting right can get hairy quickly. It might not be pretty, but `-v` is reliable. It's also better to avoid backticks for similar reasons.
Dennis Williamson
@dennis: input file: ah yes, thanks. does it matter, performance-wise? quoting: can't see how reliability is an issue; also I find the quoting used above very easy to read but it does take practice (ie. you need to know how shell quoting works!)
rosenfield