The Basics

awk is treat each line as a table, by default space are separators of columns.

General syntax is awk 'search {action}' file_to_parse.

1# Give the value higher than 75000 in column $4
2df | awk '$4 > 75000'   
3
4# Print the all line when column $4 is higher than 75000
5df | awk '$4 > 75000 {print $0}' 

But if you look for a string, the search need to be included in /search/ or ;search;.
When you print $0 represent the all line, $1 first column, $2 second column etc.

Alternative to awk can be nawk or gawk.

Awk Output

In General, as an action you want to { print } as this example:

 1# Print different columns
 2date | awk '{print "Month :" $2 "\nYear :" $6}'   
 3
 4# Pass the all line in uppercase
 5awk '{print $0=toupper($0)}'
 6
 7# Call awk script
 8awk -f file
 9
10# print the all lines with line number in front of.
11awk '{print NR, $0}'

When you print:

  • $0 represent the all line
  • $1 first column
  • $2 second column etc.
  • NR print Line number
  • NF number of columns

Field Seperator

 1awk -v FS="|" -v OFS="*" -v IGNORECASE=1  
 2# -v          =  define a variable
 3# FS="|"      =  Field Separator
 4# OFS         =  Output Field Separator
 5# FS=OFS="|"  =  set both with same value
 6
 7# Another way to define FS is with argument "-F"
 8awk -F';'      
 9
10# Define several FS ("space" + ":" and "tabs") 
11awk -F'[ :\t]' 

Example

 1# look in column 2 for lines with 4 caracters
 2awk '$2 ~ /^....$/{print $0}' awkdata.txt 
 3
 4# Operator and REGEX - exclude lines which start with D or C in cloumn 2, so you get all the rest. 
 5awk '$2 !~ /^D|^C/{print $0}' awkdata.txt
 6
 7# Several conditions AND/OR 
 8lsblk -lnb | awk '/disk/ &&  $4=='380968960' || $4=='2147487744' {print $1}'
 9
10# Search for a REGEX and Substitute before to print last column
11 curl -Lis https://github.com/ | awk '/<title>.*GitHub<\/title>/ {sub(/<\/title>/,"");print $NF}'
12
13# Find a word after a search
14awk '{for (I=1;I<NF;I++) if ($I == "as") print $(I+1)}'
15
16# Similar Output than command id:
17# - END is the output display at the end 
18# - several if conditions 
19awk -F: 'END {print "uid:"u" gid:"g" groups:"gg}{if($1=="Uid"){split($2,a," ");
20u=a[1]}if($1=="Gid"){split($2,a," ");
21g=a[1]}if($1=="Groups"){gg=$2}}' /proc/self/status

Alternative to AWK

 1# Get everything after third delimiter "_"
 2ps -ef | grep ora_pmon | grep -v grep  | awk '{print $NF}' | cut -d"_" -f3-
 3
 4# Cut the 2 last characters 
 5hostname -s | rev | cut -c 3- | rev
 6
 7# Same thing simplier
 8echo ${HOSTNAME:: -2}
 9
10# Result => 172.16.230
11ip -4 -o addr show | grep ${nic_interconnect} | awk '{print $4}'| sed 's/\/30$//' | cut -d'.' -f-3
12
13# Result =>  230.61
14ip -4 -o addr show | grep ${nic_interconnect} | awk '{print $4}'| sed 's/\/30$//' | cut -d'.' -f3-
  • Use case with a small script to backup and push resolv.conf
1#!/bin/bash
2for line in `cat expect_dns_no_nm.csv`; do
3hostname=`echo $line | cut -d";" -f1`
4username=`echo $line | cut -d";" -f2`
5password=`echo $line | cut -d";" -f3`
6 
7./expect.us ssh $hostname $username $password "cp /etc/resolv.conf /etc/resolv.conf.20151103"
8./expect.us scp $hostname $username $password source/resolv.conf /etc/resolv.conf
9done