awk — IPv6
Extract IPv6 addresses from ip -6 addr show
ip -6 addr show | awk '/inet6/{split($2,a,"/"); print $NF, a[1], "/"a[2]}'
Extract only global-scope IPv6 addresses — skip link-local
ip -6 addr show scope global | awk '/inet6/{split($2,a,"/"); print a[1]}'
Parse ip -6 route — destination, via, device
ip -6 route | awk '{
dst=$1; dev=""; via=""
for(i=2;i<=NF;i++){
if($i=="dev") dev=$(i+1)
if($i=="via") via=$(i+1)
}
printf "%-40s via %-30s dev %s\n", dst, (via?via:"-"), dev
}'
Extract remote IPv6 and port from ss -6 -tn
ss -6 -tn | awk 'NR>1 {
peer=$5
n=split(peer,a,":")
port=a[n]
addr=substr(peer,1,length(peer)-length(port)-1)
gsub(/^\[|\]$/,"",addr)
printf "%-40s port %s\n", addr, port
}'
Count IPv6 connections per remote address
ss -6 -tn | awk 'NR>1 {
peer=$5
n=split(peer,a,":")
port=a[n]
addr=substr(peer,1,length(peer)-length(port)-1)
gsub(/^\[|\]$/,"",addr)
count[addr]++
} END{for(a in count) printf "%-40s %d\n", a, count[a]}' | sort -k2 -rn
Classify IPv6 — link-local vs global vs ULA vs loopback
ip -6 addr show | awk '/inet6/{
split($2,a,"/"); addr=a[1]
if(addr ~ /^fe80/) type="link-local"
else if(addr ~ /^fd/) type="ULA"
else if(addr ~ /^fc/) type="ULA"
else if(addr == "::1") type="loopback"
else type="global"
printf "%-8s %s\n", type, addr
}'
Classify arbitrary IPv6 list from heredoc
awk '{
addr=$1
if(addr ~ /^fe80/) type="link-local"
else if(addr ~ /^f[cd]/) type="ULA"
else if(addr == "::1") type="loopback"
else if(addr ~ /^ff/) type="multicast"
else type="global"
printf "%-10s %s\n", type, addr
}' <<'EOF'
fe80::1a2b:3c4d:5e6f:7890
2607:f8b0:4004:800::200e
fd12:3456:789a::1
::1
ff02::1
2001:db8::42
EOF
Parse IPv6 neighbor table — address, device, state
ip -6 neigh | awk '{
addr=$1; dev=""; lladdr=""; state=$NF
for(i=2;i<=NF;i++){
if($i=="dev") dev=$(i+1)
if($i=="lladdr") lladdr=$(i+1)
}
printf "%-40s dev %-8s mac %-18s %s\n", addr, dev, (lladdr?lladdr:"-"), state
}'
Extract AAAA records from dig output
dig AAAA google.com +short | awk '/^[0-9a-f:]+$/{print}'
Extract AAAA from dig full output — answer section only
dig AAAA google.com | awk '/^;; ANSWER SECTION:/{p=1; next} /^;;/{p=0} p && /AAAA/{print $1, $5}'
Expand compressed IPv6 to full 8-group notation
echo "2001:db8::42" | awk -F: '{
# Count existing groups and find :: position
n=NF; expand=0
for(i=1;i<=n;i++) if($i=="") expand=i
# Build full 8 groups
g=0
for(i=1;i<=n;i++){
if($i=="" && !done){
need=9-n # groups to insert (9 because :: splits into 2 empty fields)
for(j=1;j<=need;j++) group[++g]="0000"
done=1
} else if($i!=""){
group[++g]=sprintf("%04s",$i)
gsub(/ /,"0",group[g])
}
}
for(i=1;i<=8;i++) printf "%s%s", group[i], (i<8?":":"\n")
}'
Compress full IPv6 — strip leading zeros (partial compression)
echo "2001:0db8:0000:0000:0000:0000:0000:0042" | awk -F: '{
for(i=1;i<=NF;i++){
v=$i+0 # force numeric to strip leading zeros
printf "%x%s", v, (i<NF?":":"\n")
}
}'