Shell - Awk - If with variables - shell

I have a problem with my shell script. The thing I need is something like this: How can I compare variable in if condition in awk argument. "If $variable is same as the third column $3 .. print the third column". It doesn't work for me.
variable=large
awk '{if ($3 == $variable) print "\n" $3}' temp

variable=large
awk -v var="$variable" '{if ($3 == var) print "\n" $3}' temp

Related

How do I set a built in variable in awk command to global variable?

Currently, my script parses through a file and looks for specific patterns. Each pattern is different from the other and are mutually exclusive within the file. e.g. If '$identifier1' is found, then '$identifier2' and '$identifier3' cannot be in the file.
exist=`awk -v v1="$identifer1" -v v2="$identifier2" -v v3="$identifier3" 'BEGIN{FS=":"; OFS="-"} $2 == v1 || $2 == v2 || $2 == v3 {print}' $file`
Here is the issue: during the comparison ($2 == v1 || $2 == v2 || $2 == v3), how can I set $2 as a global variable where I can use it outside of the awk command?
Any help is appreciated.
Could you please try following once but your question is not clear. In case you want to check a different field than 2nd then change value of variable named field_value and awk will look for that specific field then.
field_value="2"
exist=$(awk -v v1="$identifer1" -v v2="$identifier2" -v v3="$identifier3" -v field="$field_value" 'BEGIN{FS=":"; OFS="-"} $field == v1 || $field == v2 || $field == v3 {print}' "$file")
Maybe can't directly, but if a temporary IO is ok with you...
You can write $2 to a temporary file and later read into variable, like this:
exist=`awk -v v1="$identifer1" -v v2="$identifier2" -v v3="$identifier3" 'BEGIN{FS=":"; OFS="-"} $2 == v1 || $2 == v2 || $2 == v3 {print} {printf $2>"_tmpfile_for_v_"}' $file`
tmpv=$(<_tmpfile_for_v_)
rm _tmpfile_for_v_
Now you can use the $tmpv stored $2.
Btw the awk command can improve a little bit:
awk -v v1="$identifer1" -v v2="$identifier2" -v v3="$identifier3" 'BEGIN{FS=":"; OFS="-"} {printf $2>"_tmpfile_for_v_"} $2 == v1 || $2 == v2 || $2 == v3 ' $file
Where no block given, {print} is implied.
You did not give testdata, so I will demonstrate how you can set an extra variable with a simplified question.
Suppose you have a file with only one line starting with 1 (a line like 1 2 3).
How can you use awk for filling two variables, one with the line starting with 1 and one with the second field?
You can find the line with
line=$(awk '/^1/ {print}' file)
Now you would like to do something like
awk '/1^/ {print "line=" $0; print "field2=" $2}' file
When you know that the line doesn't has a #, you can use
IFS='#" read -r line field2 <<< $(awk '/^1/ {print $0 "#" $2}' file

Unable to substract two variable in shell scripting

I am writing a script that's picking up two values from a file and then subtracting them.But I am unable to do substraction as it is throwing error.
res1= awk 'FNR == '${num1}' {print $1}' /home/shell/test.txt
res2= awk 'FNR == '${num2}' {print $1}' /home/shell/test.txt
res= $((res2 - res1))
echo $res
I also tried expr = `expr $res2 -$res1` but it didn't work. please help me so as to get the desired result.
your assignments for res1/res2 are wrong. It should be
res1=$(awk 'FNR == '${num1}' {print $1}' /home/shell/test.txt)
However, you can do it all in awk
$ num1=5; num2=2; awk -v n1=${num1} -v n2=${num2} 'FNR==n1{r1=$1;f1=1}
FNR==n2{r2=$1;f2=1}
f1&&f2{print r1-r2; exit}' <(seq 5)
3
This is because there is one space char after each = sign: res1= awk
Remove the spaces and use $( command ) to execute a command and gather its output.
Give a try to this:
res1="$(awk -v num=${num1} 'FNR == num {print $1}' /home/shell/test.txt)"
res2="$(awk -v num=${num2} 'FNR == num {print $1}' /home/shell/test.txt)"
res=$(( res2 - res1 ))
printf "%d\n" ${res}
I had read in another answer that it is preferred to pass variable's value to awk script using -v var_name=value, rather than concatenating strings.

awk working with intervals

I have this file
goodtime 20:30 21:40
badtime 19:52 24:00
and when I enter for example 21:00 and 21:15 I should get goodtime
So here's my script
#!/bin/sh
last > duom.txt
grep -F 'stud.if.ktu.lt' duom.txt > ktu.txt
echo "Nurodykite laiko intervala "
read h
read min
read h2
read min2
awk '{if ($2 ~ /$h.$m/ && $3 ~ /$h2.$min2/) print $1}' data.txt
But I don't get any results.
The problem with this:
awk '{if ($2 ~ /$h.$m/ && $3 ~ /$h2.$min2/) print $1}' data.txt
Is that you're trying to use shell variables in a single quoted string. You need to pass the shell variables into awk with its -v option:
awk -v patt1="$h.$min" -v patt2="$h2.$min2" '
$2 ~ patt1 && $3 ~ patt2 {print $1}
' data.txt
But, given your sample input, this will not match anything.
Until your requirements are clarified, I can't help with the logic.

Bash: AWK - $1 as first parameter of shell script

I spent on this 2 hours and get nothing. I want to get $1 and $2 as a first command line input of shell script, but I couldn't manage this. And $3 and $0 would be columns in awk. I try different methods but nothing works for me.
awk -F':' -v "limit=1000" '{ if ( $3 >=limit ) gsub("~/$1/",~/$2/); print \$0}' file.txt
the cleanest method is to explicitly pass the values from shell to awk with awk's -v option:
awk -F: -v limit=1000 -v patt="~/$1/" -v repl="~/$2/" '
$3 >=limit {gsub(patt,repl); print}
' file.txt
When your awk line is part of a script file, and you want to use $1 and $2 from the script in your awk command, you should temporary stop the literal string with a single quote and start it again.
awk -F':' -v "limit=1000" '{ if ( $3 >=limit ) gsub("~/'$1'/",~/'$2'/); print $0}' file.txt
You didn't post any sample input or expected output so this is a guess but you probably want something like this:
awk -F':' -v limit=1000 -v arg1="$1" -v arg2="$2" '$3 >= limit{gsub("~/" arg1 "/","~/" arg2 "/"); print}' file.txt

How to insert Command Line argument of shell script in AWK?

I have to find all of the record which have a particular data which I am gonna pass as the command line argument.
awk expression is like this(Date is in this format :'02/08/2013')
cat records.txt| awk -F ',' '$4 ~ /02/08/2013/ {print $1 $2}'
Here 4th column is the date column.
What I want to do is that, provide the date as the first argument and compare it.
I tried this,But it is not working.
cat records.txt| awk -F ',' -v awkvar="$1" '$4 ~ /^"awkvar/ {print $1 $2}'
Here the date column starts with " quote, so I am telling to look for the records who start with "+awkvar the given date.
Can anyone help me with this?
Edit:
awk -F ',' -v var1="$1" '$4 ~ /^"2013/ {print $1 $2}' {This one is working, as I am directly comparing the record with 2013}
when I do this
awk -F ',' -v var1="$1" '$4 ~ /^"var1/ {print $1 $2}' , it does not return anything, what is the difference.
To pass variables to awk, use
awk -v awkvar=$value '{print awkvar}'
That said, no need to pipe cat | awk (useless use of cat) so finally :
awk -F, -v awkvar="$1" '$4 ~ "^\""awkvar {print $1 $2}' records.txt

Resources