Awk: print lines with one of multiple pattern in the same field (column)

Hi all,

I am new to using awk and am quickly discovering what a powerful pattern-recognition tool it is. However, I have what seems like a fairly basic task that I just can't figure out how to perform in one line. I want awk to find and print all the lines in which one of multiple patterns (e.g. "A" or "B") appears in a column.

I've gotten this far:

awk '$3 == "A" {print $0}' file.txt > newfile.txt
awk '$3 == "B" {print $0}' file.txt >> newfile.txt

but I really want to be able to specify in one step "A" OR "B"...

Many thanks!

It should be as follows:

awk '$3=="A";$3=="B" {print $0}' file.txt

Regards,
Srikanth

1 Like

If you are looking for pattern match and not for a strict comparison, use ~ operator:

awk '$3 ~ /A/ || $3 ~ /B/' file.txt
1 Like
$ awk '$3 ~ /A|B/' file
1 Like
awk '$3=="A" || $3=="B"  {print $0}'  file.txt 
1 Like
$ cat <<test | awk '$1 ~ /A|B/'
A
C
B
BB
D
test
A
B
BB

$ cat <<test | awk '$1 ~ A || $1 ~ B' # Variable  ???
A
C
B
BB
D
test

A
C
B
BB
D

$ cat <<test | awk '$1 ~ /A/ || $1 ~ /B/'
A
C
B
BB
D
test

A
B
BB

$ cat <<test | awk '$1 ~ A || $1 ~ B' A=A B=B
A
C
B
BB
D
test

A
B
BB

$ cat <<test | awk '$1 ~ "A" || $1 ~ "B"'
A
C
B
BB
D
test

A
B
BB

Hello,

with strict match:

awk -vs1="A" -vs2="B" '$3==s1 || $3==s2 {print}' file_name

with non-strict match:

awk -vs1="A" -vs2="B" '$3~s1 || $3~s2 {print}' file_name

Thanks,
R. Singh

great! I knew there had to be a simple and elegant way!

---------- Post updated at 11:46 AM ---------- Previous update was at 11:43 AM ----------

So it looks like this one will return lines with "AB" and "BA" as well as "A" and "B."

Whereas

awk '$3=="A";$3=="B" {print $0}' file.txt

will return only lines that exactly match "A" and "B."

Getting "AB" and "BA" also is actually exactly what I needed (without realizing it initially!). Thanks, all!

Solutions if the order does not matter:

awk '
$3=="A" {print $0}
$3=="B" {print $0}
' file.txt
awk '
$3=="A" || $3=="B" {print $0}
' file.txt
awk '
$3~/^(A|B)$/ {print $0}
' file.txt

(line start/end boundaries required to be equavilent to == )
If the order matters, first all A matches then all B matches:

awk '
NF==FNR && $3=="A" {print $0}
NF!=FNR && $3=="B" {print $0}
' file.txt file.txt
awk '
$3=="A" {print $0} # print immediately
$3=="B" {B[++b]=$0} # store for later
END {
 for (i=1; i<=b; i++) print B
}
' file.txt

---------- Post updated at 12:01 PM ---------- Previous update was at 11:56 AM ----------

Then it's shorter

awk '$3 ~ /[AB]/ {print $0}' file.txt 

Note that {print} is short for {print $0}
And that after a condition without {} there is an implicit {print} :

awk '$3 ~ /[AB]/' file.txt
1 Like