Thứ Sáu, 18 tháng 1, 2013

[Shell] Awk trong lập trình Shell Linux

Gợi ý tham khảo:  Cách dùng AWK để liệt kê các loại user trong Linux bằng shell

Cách dùng awk để quét và xử lý ngôn ngữ theo dạng scripts? Một vài ví dụ ?

Awk là một công cụ hữu hiệu cho xây dựng UNIX/Linux shell scripts. AWK là một ngôn ngữ lập trình thiết kế cho xử lý dữ liệu thuần dạng test, cả trong file hay data streams, hoặc dùng shell pipes. Nói cách khác, ta có thể kết hợp awk với shell scripts hoặc dùng trực tiếp trong command.

In một file test ra màn hình

awk '{ print }' /etc/passwd
hay
awk '{ print $0 }' /etc/passwd

In ra một trường cụ thể

Dùng : (In trường đầu tiên. bỏ qua các trường khác):
awk -F':' '{ print $1 }' /etc/passwd
Xuất output sau đó sort (sắp xếp) bằng cách dùng dấu | (shell pipe):
awk -F':' '{ print $1 }' /etc/passwd | sort

Đối chiếu mẫu

Bạn còn in dòng sau khi đối chiếu, ví dụ hiển thị tất cả dòng từ file log của Apache nếu HTTP error code bằng 500 ( trường thứ 9 ($9) là logs status error code cho mỗi yêu cầu http ):
awk '$9 == 500 { print $0}' /var/log/httpd/access.log
Đây là các phép so sánh có thể dùng trong awk:
== != < > <= >= ?:
If no pattern is given, then the action applies to all lines. If no action is given, then the entire line is printed. If "print" is used all by itself, the entire line is printed. Thus, the following are equivalent:
awk '$9 == 500 ' /var/log/httpd/access.log
awk '$9 == 500 {print} ' /var/log/httpd/access.log
awk '$9 == 500 {print $0} ' /var/log/httpd/access.log

In dòng có từ tom, jerry và vivek:

awk '/tom|jerry|vivek/' /etc/passwd

In dòng thứ 1 từ file

awk "NR==1{print;exit}" /etc/resolv.conf
awk "NR==$line{print;exit}" /etc/resolv.conf

Phép tính đơn giản

Tính tổng của các số trong 1 cột:
awk '{total += $1} END {print total}' earnings.txt
Shell không thể tính với số thực, nhưng awk có thể;
awk 'BEGIN {printf "%.3f\n", 2005.50 / 3}'

Tham khảo thêm:

Call AWK From Shell Script

A shell script to list all IP addresses that accessing your website. This script use awk for processing log file and verification is done using shell script commands.
#!/bin/bash
d=$1
OUT=/tmp/spam.ip.$$
HTTPDLOG="/www/$d/var/log/httpd/access.log"
[ $# -eq 0 ] && { echo "Usage: $0 domain-name"; exit 999; }
if [ -f $HTTPDLOG ];
then
 awk '{print}' $HTTPDLOG >$OUT
 awk '{ print $1}' $OUT  |  sort -n | uniq -c | sort -n
else
 echo "$HTTPDLOG not found. Make sure domain exists and setup correctly."
fi
/bin/rm -f $OUT

AWK and Shell Functions

Here is another example. chrootCpSupportFiles() find out the shared libraries required by each program (such as perl / php-cgi) or shared library specified on the command line and copy them to destination. This code calls awk to print selected fields from the ldd output:
 
chrootCpSupportFiles() {
# Set CHROOT directory name
local BASE="$1"         # JAIL ROOT
local pFILE="$2"        # copy bin file libs
 
[ ! -d $BASE ] && mkdir -p $BASE || :
 
FILES="$(ldd $pFILE | awk '{ print $3 }' |egrep -v ^'\(')"
for i in $FILES
do
  dcc="$(dirname $i)"
  [ ! -d $BASE$dcc ] && mkdir -p $BASE$dcc || :
  /bin/cp $i $BASE$dcc
done
 
sldl="$(ldd $pFILE | grep 'ld-linux' | awk '{ print $1}')"
sldlsubdir="$(dirname $sldl)"
if [ ! -f $BASE$sldl ];
then
        /bin/cp $sldl $BASE$sldlsubdir
else
        :
fi
}
This function can be called as follows:
chrootCpSupportFiles /lighttpd-jail /usr/local/bin/php-cgi

AWK and Shell Pipes

List your top 10 favorite commands:
history | awk '{print $2}' | sort | uniq -c | sort -rn | head
Sample Output:
   172 ls
    144 cd
     69 vi
     62 grep
     41 dsu
     36 yum
     29 tail
     28 netstat
     21 mysql
     20 cat
whois cyberciti.com | awk '/Domain Expiration Date:/ { print $6"-"$5"-"$9 }'

Awk Program File

You can put all awk commands in a file and call the same from a shell script using the following syntax:
awk -f mypgoram.awk input.txt

Awk in Shell Scripts - Passing Shell Variables TO Awk

You can pass shell variables to awk using the -v option:
 
n1=5
n2=10
echo | awk -v x=$n1 -v y=$n2 -f program.awk
Assign the value n1 to the variable x, before execution of the program begins. Such variable values are available to the BEGIN block of an AWK program:
BEGIN{ans=x+y}
{print ans}
END{}

1 nhận xét:

  1. VAR=`awk 'BEGIN{print ("'$Y'" < "'0'") ? 1:0}'`
    trong câu lệnh trên, trường hợp Y=0.8, nhưng mình cho hiển thị giá trị Y lên thì kết quả là Y=.8, mình so sánh với 0 nó cho ra kết quả VAR=1, như vậy thì phải làm sao để xử lý được trường hợp này vì 0.8>0 mà

    Trả lờiXóa