AWK command in Linux

Harsh Hatej
4 min readApr 2, 2024

--

The awk command in Linux is a powerful text-processing utility that allows you to manipulate and analyze text data in files or streams. It operates on a per-line basis, splitting each line into fields based on a specified delimiter (by default, whitespace), and then allows you to perform various operations on these fields.

Some more details about AWK :

  • Searches files for lines that contain certain patterns
  • Performs operation described in AWK body on line with cerain pattern
  • Performs operation described in AWK body on choosen line
  • In AWK body bash features dosen’t work
  • Completely new language in AWK body
  • Completely new features we can call on specific line (specific text)

AWK can filter the file both horizontally and vertically at the same time.

Basic Structure of AWK command :

awk 'BEGIN{code_in_BEGIN_section}{code_in_main_body_section} End {Code_in_END_section} input-file1 input-file2
awk 'BEGIN{code_in_BEGIN_section}
{code_in_main_body_section}
END{code_in_END_section}' input-file1 input-file2
awk -F: '{print$0}' /etc/passwd /etc/shadow /etc/shadow
awk 'BEGIN {FS=":"} {print $1,$2}' /etc/passwd #We can also give Field Seperator in BEGIN part
awk 'BEGIN {RS=":"} {print$0}' /etc/passwd #Record Seprator can seperate records, by default it is \\n

here we used awk command and set the delimiter to ‘ : ‘ using -F switch and printed all fields of the three files.We can select different fields to print by $ sign

(*If we dont use -F switch it will consider the delimiter as space)

awk -F: '{print$1,$6,$7}' /etc/passwd #Uses space as delimiter while using(,)
awk -F: '{print$1,"-",$6}' /etc/passwd #Adds costum symbol in between the values
awk -F: '{print$1,"\\\\",$6}' /etc/passwd #To Use backlash we need to give two backslash
awk -F: '{print$1,"text ",$6}' /etc/passwd #We can add any text also in between

Now to filter out a specific string :

awk -F: '/^root/ {print$0}' /etc/passwd
#filtering strings starting with "root"

ifconfig | awk '/ inet /{print$2}'
#filtering ip address using awk

We can also add begin and end part in awk like this :

ifconfig | awk 'BEGIN {print"===IP Address==="} / inet /{print$2} 
END {print "===== END ====="}'

OUTPUT ->
===IP Address===
192.168.29.21
127.0.0.1
192.168.122.1
===== END =====

We can also use begin, middle and ending part as we wish and can also use them individually:

echo "one two three four" | awk 'BEGIN{print"demo1"} {print"demo2"} 
END{print"demo3"}'
demo1
demo2
demo3

We mainly define the middle part usually, BEGIN & END part is not used much.

We can also modify any $ value :

echo Armour Infosec | awk '{$1 = "ARMOUR" ; print$0}’
ARMOUR Infosec

We can use == and != to filter out output in awk command like :

ifconfig | awk'$1=="inet" {print$2}'
#field 2nd whose first field is inet

ifconfig | awk'$1!="inet" {print$0}'
#all the fields whose 1st field is inet

awk -F: '$1=="root" {print$0}' /etc/passwd
#all the fields whose 1st field is root

awk -F: '$1!="root" {print$0}' /etc/passwd
#all the fields whose 1st field is not root

awk -F: '$3>=1000 {print$0}' /etc/passwd
#all the fields who have value greater than 1000 in 3rd field

awk -F : '/^bash/ {print$0}' /etc/passwd
#fields starting with "bash"

awk -F : '/bash&/ {print$0}' /etc/passwd
#fields ending with bash

awk -F : '/\\/sbin\\/nologin$/ {print$0}' /etc/passwd
#use of opposite slash to search for slash values (/sbin/nologin)

echo "one two three four" | awk '{print NF}'
#prints number of fields(Output = '4')

echo "one two three four" | awk '{print $NF}'
#prints last field value

echo "one two three four" | awk '{print $(NF-1)}'
#prints second last field value and so on {(NF-2) (NF-3)...}

Using Pre-Made pattern file :

Sometime the middle file pattern can be of multiple lines which can increase the confusion and things can become haywire, we can eliminate this by saving our pattern in a text file like :

vim awk_patterns.txt
BEGIN{
print "Passwd File"
}
{
print $1 , "home at" , $6
}
END{
print "End of passwd file"
}
#We can define the content in multiple lines as well as single line :
BEGIN{print "Passwd File"}{print $1 , "home at" , $6}END{print "End of passwd file"}

Now we can use the pattern file by -f switch :

awk -f awk_patters.txt -F : /etc/passwd

We can also create good looking patters like :

BEGIN{
print "User and their corresponding home"
print "User Name \\t \\t Home Path"
print "---------------\\t \\t---------------"
FS=":"
}
{
print$1,"\\t \\t \\t "$6
}
END{
print"-------------END of the file--------------"
}
OUTPUT ->User and their corresponding home
User Name Home Path
--------------- ---------------
root /root
bin /bin
daemon /sbin
adm /var/adm
lp /var/spool/lpd
sync /sbin
shutdown /sbin
halt /sbin
mail /var/spool/mail
postfix /var/spool/postfix
user1 /home/user1
userx /home/userx
-------------END of the file--------------
ps aux | awk -F" " 'BEGIN{print"USERNAME \\t PID \\t CMD"} $1==root {print$1,"\\t \\t",$2,"\\t",$11,$12,$13,$14}'
USERNAME PID CMD
root 1 /usr/lib/systemd/systemd --switched-root --system --deserialize
root 2 [kthreadd]
root 4 [kworker/0:0H]
root 6 [ksoftirqd/0]
root 7 [migration/0]
root 8 [rcu_bh]
......

We can also use awk for calculations like :

echo 4 6 | awk '{print$1+$2}'
10
echo 4 6 | awk '{print$1-$2}'
-2
echo 4 6 | awk '{print$1*$2}'
24
echo 4 6 | awk '{print$1/$2}'
0.666667

--

--