Dyanmic query in awk
Hi,
How to write Dynamic query in awk. Say I have a awk query something like : count=$(awk -F "|" '!/^#/ && !/^$/ {if( $1=="'$Name'" && $NF=="N")print $0}' $FILE |wc -l) I want to make the condition inside If statement as dyanamic Ex: var="'$'1=="C_Calendar" && '$'NF=="N""; count=$(awk -F "|" '!/^#/ && !/^$/ {if($var)print $0}' $FILE |wc -l) --> This doesn't work is it possible in awk ? |
Could you explain a little further as I am not following?
You can utilise bash variables using -v |
I want to build a dynamic query using awk,
like today if we have 2 conditions tested here tomorrow I can just modify the string and Add a third condition to test. The following query with -v option didnt work var="$1=="DANNY" && $NF=="N""; echo $var; count=echo $(awk -v $var=var -F "|" '!/^#/ && !/^$/ {if($var)print $0}' $FILE |wc -l); echo $count; Error Thrown ==DANNY && ==N awk: fatal: `' is not a legal variable name bash: 0: command not found... |
Firstly, please use [code][/code] tags when showing code or data.
Ok ... I think I get you. The short answer is no you can't at least not the way you have tried (obviously). Code:
var="$1=="DANNY" && $NF=="N""; Code:
if("==DANNY && ==N") If you are wondering why your string is incomplete: $1 will only have a value if an argument has been passed to the script $NF is only known to awk unless you create a variable in bash with the same name Hence both your strings are blank. The $ symbol in bash is used to return the value assigned to a variable whereas in awk it is used to return the indirect value (ie if NF = 6 then $NF returns the item in the sixth column) This is why $var has not worked and thrown an error in awk Your assigment for the awk variable is the wrong way around: Code:
-v $var=var So correct line would be: Code:
-v var="$var" Code:
if(var) The only way I can think of off the top of my head would be to assign all the values for the tests into a single string and then split into an array and test. If you then wanted to perform other tests, ie not just equals to, this would be come very complicated as you would need to test for the test and perform each as found?? So this method would be: Code:
var="1 DANNY NF N" |
Not only column value, the column number is also dynamic in this case.
|
I tend to agree with grail. PERL, while still a scripting language, has a bit more flexibility that you'd be looking for. OR, you could do the selection in a shell script and call an awk script to do the parsing.
|
With this InFile1 ...
Code:
four score and seven years ago our fathers brought forth Code:
6 nation Code:
awk '{if (FNR==NR){numb[NR]=$1;text[NR]=$2} Code:
four score and seven years ago our fathers brought forth |
Here is a minor variation of the solution posted earlier.
This makes the matched word STAND OUT. With this InFile1 ... Code:
four score and seven years ago our fathers brought forth Code:
6 nation Code:
awk '{if (FNR==NR){numb[NR]=$1;text[NR]=$2} Code:
FOUR score and seven years ago our fathers brought forth |
Hi Daniel,
This doesnt looks a solution for the query, it looks like dynamic qury in awk seems a little difficult. |
Daniels solution is dynamic as it means you simply add to the second file (InFile2) as many entries as you wish and those will be the rows and words searched for in the main file
|
Ok I got it. This is for Single column field,
if I need to check multiple column field (each column check having an AND condition) At any time if I want to check different columns... My query can be any of these Code:
count=$(awk -F "|" '!/^#/ && !/^$/ {if( $1=="'$Name'" && $NF=="N")print $0}' $FILE |wc -l) Code:
count=$(awk -F "|" '!/^#/ && !/^$/ {if( $1=="'$Name'" && $4=="'Place'" $NF=="N")print $0}' $FILE |wc -l) Code:
count=$(awk -F "|" '!/^#/ && !/^$/ {if( $1=="'$Name'" && $4=="'Place'" && $5=="'$Date'" && $NF=="N")print $0}' $FILE |wc -l) |
So loop over all fields and only when all true, proceed
|
WOW!
you guys are a thing of beauty to watch |
InFile1 ...
Code:
four score and seven years ago our fathers brought forth Code:
6 nation 3 continent They are: Code:
- all lines where the 6th word is nation and the 3rd word is continent Code:
awk '{if (FNR==NR) for (i=1;i<=NF;i++) crit[NR,i]=$i Code:
FOUR score and seven years ago our fathers brought forth |
Nice work Daniel. Here is another take using your data:
Code:
awk 'NR==FNR{for(i=1;i<NF;i+=2)arr[NR][$i]=$(i+1)} |
All times are GMT -5. The time now is 06:15 PM. |