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.
Related
I have a little test file containing:
awk this
and not awk this
but awk this
so do awk this
And I've tried the following awk commands, in bash, but each produces no output:
f=awk; awk '/$f/ && !/not/' test.txt
f=awk; awk '/\$f/ && !/not/' test.txt
f=awk; awk '/"$f"/ && !/not/' test.txt
f=awk; awk -v f="$f" '/f/ && !/not/' gtest.txt
Using double quotes " produces "event not found" error in the shell due to the !.
How can I search on a variable and negate another string in the same command?
Use awk like this:
f='awk'
awk -v f="$f" -v n='not' '$0 ~ f && $0 !~ n' file
awk this
but awk this
so do awk this
Or if you don't want to pass n='not' to awk:
awk -v f="$f" '$0 ~ f && $0 !~ /not/' file
awk this
but awk this
so do awk this
awk points to gawk for me and the following worked just fine:
awk -vf=awk '$0 ~ f && !/not/' file
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.
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
I am trying to count strings containing a number at the end in a large data file, and for this use the "for i loop" to search all of them consecutively. Here is my code:
#!/bin/bash
for (( i=2; i<=253; i++ ))
do
awk -F "\t" '$3 ~ /^names.i$/ {++c} END {print c}' myfile >> output.txt
done
For some reason although using awk only gives the right output, the script produces just empty spaces in shell. What do I do wrong?
Just do the whole thing in 1 awk invocation:
awk -F '\t' '
{ split($3,arr,/\./); ++c[arr[2]] }
END { for (i=2;i <= 253;i++) print c[i]+0 }
' myfile > output.txt
You can't use shell variable i directly in awk like that. Pass it to awk first:
for (( i=2; i<=253; i++ ))
do
awk -v i=$i -F "\t" '$3 ~ "^names\." i "$" {++c} END {print c}' myfile >> output.txt
done
Try this
awk -F "\t" '{for (i=2;i<=253;i++) if ($3 ~ /^names.i$/) ++c} END {print c}' myfile
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