4

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.

2
  • Why don't you tell us the error you're getting ;) Commented Oct 14, 2009 at 22:00
  • 6
    cheri, you need to learn the difference between the pipe character | and the lower case letter "ell", and also how to properly use quotes (single and double). A basic shell tutorial would help. Commented Oct 14, 2009 at 23:04

6 Answers 6

10

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
Sign up to request clarification or add additional context in comments.

1 Comment

Note this still has the OP's typo with the missing $ on the echo command.
3

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.

3 Comments

The /^var1 var2/ is redundant and the ";" makes the matches before it print every input line (since there's no action before the semicolon).
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, thanks. Good catches. I probably should have just stuck with my original with grep. I think that's the better way to go anyway.
1

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

Comments

0

Or perhaps:

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

If your vars need to be in either order?

1 Comment

$1 and $2 are awk fields in this context, not positional parameters. The pertinent variables are $VA1 and $VA2.
0

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

5 Comments

It's better to pass in the variables with -v rather than play tricks with quoting.
@glenn: huh? define "better"? it sure aint prettier
@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: 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, in a case where VA1 etc have known values, as here, quoting is fine. But if it turns out that VA1 may contain, for example, foo/{next} /bar, you'll wish you had gotten into the habit of using -v instead.
0

I know this is an old post but awk is even older and still in use - and people are still looking for the same answers. I suppose I was an example of this.

I decided to implement a similar scenario but wanted predefined variables in the config file. The user passes the partial name of config file to script as first parameter.

cfg=$PWD/$1.cfg

foo=$(awk '$1 ~ /foo/ { print $2 }' $cfg)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.