Awk multiple search terms with a variable and negation - bash

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

Related

Bash variable in AWK [duplicate]

This question already has answers here:
How do I use shell variables in an awk script?
(7 answers)
Closed 4 years ago.
I'm trying to pass variable in loop with awk command to find values. I have a file:
input.txt
1234|something|ohmygod
2345|urabura|kangura
9999|1234|xxxsecrets
shell command
cat input.txt | awk -F'|' '$1 ~ /1234/'
or
awk -F'|' '$1 ~ /1234/' input.txt
get first line from file as desired. Problem occurs when I try to print this via bash. When I simply test echo like:
echo `cat input.txt | awk -F'|' '$1 ~ /1234/'`
or
echo `awk -F'|' '$1 ~ /1234/' input`
I got desired output, but unfortunately when I try to pass variable inside it
variable1="1234"
echo `awk -F'|' '$1 ~ /"$variable1"/' input`
or
variable1="1234"
echo `awk -v var="$variable1" -F'|' '$1 ~ /var/' input`
it gives one empty line. Please suggest how to pass variable inside regex awk filter.
PS It is not duplicate question to: How do I use shell variables in an awk script? due to fact that I have knowledge how to use variable in AWK as I posted up here (-v parameter) but the question is how to PASS variable in REGEX in AWK (place between two slashes - echo awk -F'|' '$1 ~ /"$variable"/' input)
What you asked for:
awk -v var="$variable1" -F'|' '$1 ~ var' input
What you actually need:
awk -v var="$variable1" -F'|' '$1 == var' input
See http://cfajohnson.com/shell/cus-faq-2.html#Q24

How to avoid generating intermediate files in bash script

I would like to know if it is possible to change the following script, such that "intermediate.tmp" is not generated as output:
To call the script on the command line:
./script.sh file1 file2
script.sh:
#!/bin/bash
FILE_1=$1
FILE_2=$2
awk '{print $1,$2}' $FILE_1 > intermediate.tmp
awk 'NR==FNR {h[$1] = $0; next} {print $0,h[$1]}' intermediate.tmp $FILE_2 > output.file
The awk scripts are not really important per se. I just want to know how to "feed" intermediate.tmp into the second awk command without generating an intermediate.tmp output file in addition to the desired output.file.
Thanks.
awk 'NR==FNR {h[$1] = $1 OFS $2; next} {print $0,h[$1]}' "$FILE_1" "$FILE_2" > output.file
or less sensibly:
awk '{print $1,$2}' "$FILE_1" |
awk 'NR==FNR {h[$1] = $0; next} {print $0,h[$1]}' - "$FILE_2" > output.file

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