6

I want to print the lines that with two columns equal to a variable, for example, input:

2607s1  NC_000067.6 95.92   49  1   1   3   50  1e-14   84.2
2607s1  NC_000067.6 97.73   44  1   0   7   50  4e-14   84.2
2607s1  NC_000067.6 97.67   43  1   0   8   50  1e-13   75.0

and variables for first and last column:

a="2607s1"; b="84.2"

and using awk command, output:

2607s1  NC_000067.6 95.92   49  1   1   3   50  1e-14   84.2
2607s1  NC_000067.6 97.73   44  1   0   7   50  4e-14   84.2

I have tried the following but not work:

awk -v '$1==$a' && '$10==$b' test_file
cat test_file|awk '$1=="($a)" && $10=="($b)"'
cat test_file|awk '$1==($a) && $10==($b)'
cat test_file|awk '$1=="$a" && $10=="$b"'

Moreover, I am running it in a while loop, so the $a and $b keep changing Please help..

1
  • wrt I am running it in a while loop - using a shell loop just to manipulate text is always the wrong approach. The end result is invariably lengthy, awkward, fragile, error prone, slow and generally bad software since that is not what shell is for. You might want to ask for help with that part of the bigger script in a separate question. Commented Jun 3, 2015 at 10:45

3 Answers 3

15

You are passing the shell variables to the awk command using a wrong method. It should be like

awk -v a="$a" -v b="$b" '$1==a && $10 == b' 

What it does

  • -v a="$a" creates an awk variable a and assigns the value of shell variable $a to it.

  • -v b="$b" Creates awk variable b.

OR

awk '$1==a && $10 == b' a="$a" b="$b" file

When you write a statement like this

awk -v '$1==$a' && '$10==$b' test_file

awk doesn't know what $a $b is because both are shell variables.

And the correct method of using -v for passing shell variables is as in demonstrated in the examples.

From awk manuals

-v var=val

   --assign var=val

    Assign  the  value  val to the variable var, before execution of
    the program begins.  Such variable values are available  to  the
    BEGIN block of an AWK program.


Test

$ cat file 
2607s1  NC_000067.6 95.92   49  1   1   3   50  1e-14   84.2
2607s1  NC_000067.6 97.73   44  1   0   7   50  4e-14   84.2
2607s1  NC_000067.6 97.67   43  1   0   8   50  1e-13   75.0

$ a="2607s1"; b="84.2"

$ awk -v a="$a" -v b="$b" '$1==a && $10 == b' file 
2607s1  NC_000067.6 95.92   49  1   1   3   50  1e-14   84.2
2607s1  NC_000067.6 97.73   44  1   0   7   50  4e-14   84.2
Sign up to request clarification or add additional context in comments.

6 Comments

it works!, is it possible not to use the -v flag in this case?
@once I afraid not :( It is the only method of passing shell variables onto the awk script.
It isn't the only way, although it is the best. You can also do awk '$1==a && $10 == b' a="$a" b="$b" file
@User112638726 Ooch I really missed that. Will add to answer. Thank you
Yeah there is another method as well. I missed it in the first place. see the updated answer or comment by @User112638726
|
4

You can also do this (this avoids using -v parameters)

awk '$1=="'$a'" && $10=="'$b'"' file

The quote ' just before $a will turn off string interpretation.

The quote ' just after $a will turn on string interpretation.

$a is in this way interpreted and replaced by its value.

Comments

1

You may try the below awk command.

awk -v var1="$a" -v var2="$b" '$1==var1&&$NF==var2' file

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.