# AWK內置函數

AWK許多內置函數，隨時可爲程序員使用。本教程介紹了AWK的算術，字符串，時間，位操作和其他雜項函數的例子：

## 算術函數

AWK具有以下內置的算術函數：

### atan2(y, x)

[jerry]\$ awk 'BEGIN {
PI = 3.14159265
x = -10
y = 10
result = atan2 (y,x) * 180 / PI;

printf "The arc tangent for (x=%f, y=%f) is %f degrees\n", x, y, result
}'

The arc tangent for (x=-10.000000, y=10.000000) is 135.000000 degrees

### cos(expr)

[jerry]\$ awk 'BEGIN {
PI = 3.14159265
param = 60
result = cos(param * PI / 180.0);

printf "The cosine of %f degrees is %f.\n", param, result
}'

The cosine of 60.000000 degrees is 0.500000.

### exp(expr)

[jerry]\$ awk 'BEGIN {
param = 5
result = exp(param);

printf "The exponential value of %f is %f.\n", param, result
}'

The exponential value of 5.000000 is 148.413159.

### int(expr)

[jerry]\$ awk 'BEGIN {
param = 5.12345
result = int(param)

print "Truncated value =", result
}'

Truncated value = 5

### log(expr)

[jerry]\$ awk 'BEGIN {
param = 5.5
result = log (param)

printf "log(%f) = %f\n", param, result
}'

log(5.500000) = 1.704748

### rand

[jerry]\$ awk 'BEGIN {
print "Random num1 =" , rand()
print "Random num2 =" , rand()
print "Random num3 =" , rand()
}'

Random num1 = 0.237788
Random num2 = 0.291066
Random num3 = 0.845814

### sin(expr)

[jerry]\$ awk 'BEGIN {
PI = 3.14159265
param = 30.0
result = sin(param * PI /180)

printf "The sine of %f degrees is %f.\n", param, result
}'

The sine of 30.000000 degrees is 0.500000.

### sqrt(expr)

[jerry]\$ awk 'BEGIN {
param = 1024.0
result = sqrt(param)

printf "sqrt(%f) = %f\n", param, result
}'

sqrt(1024.000000) = 32.000000

### srand([expr])

[jerry]\$ awk 'BEGIN {
param = 10

printf "srand() = %d\n", srand()
printf "srand(%d) = %d\n", param, srand(param)
}'

srand() = 1
srand(10) = 1417959587

## 字符串函數

AWK具有以下內置字符串函數：

### asort(arr [, d [, how] ])

[jerry]\$ awk 'BEGIN {
arr[0] = "Three"
arr[1] = "One"
arr[2] = "Two"

print "Array elements before sorting:"
for (i in arr) {
print arr\[i\]
}

asort(arr)

print "Array elements after sorting:"
for (i in arr) {
print arr\[i\]
}

}'

Array elements before sorting:
Three
One
Two
Array elements after sorting:
One
Three
Two

### asorti(arr [, d [, how] ])

[jerry]\$ awk 'BEGIN {
arr["Two"] = 1
arr["One"] = 2
arr["Three"] = 3

asorti(arr)

print "Array indices after sorting:"
for (i in arr) {
print arr\[i\]
}

}'

Array indices after sorting:
One
Three
Two

### gsub(regex, sub, string)

gsub代表全局替換。它用正則表達式分每個匹配。第三個參數是可選的，如果省略它，那麼\$0被使用。

[jerry]\$ awk 'BEGIN {
str = "Hello, World"

print "String before replacement = " str

gsub("World", "Jerry", str)

print "String after replacement = " str

}'

String before replacement = Hello, World
String after replacement = Hello, Jerry

### index(str, sub)

[jerry]\$ awk 'BEGIN {
str = "One Two Three"
subs = "Two"

ret = index(str, subs)

printf "Substring \\"%s\\" found at %d location.\\n", subs, ret

}'

Substring "Two" found at 5 location.

### length(str)

[jerry]\$ awk 'BEGIN {
str = "Hello, World !!!"

print "Length = ", length(str)

}'

Length = 16

### match(str, regex)

[jerry]\$ awk 'BEGIN {
str = "One Two Three"
subs = "Two"

ret = match(str, subs)

printf "Substring \\"%s\\" found at %d location.\\n", subs, ret

}'

Substring "Two" found at 5 location.

### split(str, arr, regex)

[jerry]\$ awk 'BEGIN {
str = "One,Two,Three,Four"

split(str, arr, ",")

print "Array contains following values"

for (i in arr) {
print arr\[i\]
}

}'

Array contains following values
One
Two
Three
Four

### sprintf(format, expr-list)

[jerry]\$ awk 'BEGIN {
str = sprintf("%s", "Hello, World !!!")

print str

}'

Hello, World !!!

### strtonum(str)

[jerry]\$ awk 'BEGIN {
print "Decimal num = " strtonum("123")
print "Octal num = " strtonum("0123")
print "Hexadecimal num = " strtonum("0x123")
}'

Decimal num = 123
Octal num = 83
Hexadecimal num = 291

### sub(regex, sub, string)

[jerry]\$ awk 'BEGIN {
str = "Hello, World"

print "String before replacement = " str

sub("World", "Jerry", str)

print "String after replacement = " str

}'

String before replacement = Hello, World
String after replacement = Hello, Jerry

### substr(str, start, l)

[jerry]\$ awk 'BEGIN {
str = "Hello, World !!!"
subs = substr(str, 1, 5)

print "Substring = " subs

}'

Substring = Hello

### tolower(str)

[jerry]\$ awk 'BEGIN {
str = "HELLO, WORLD !!!"

print "Lowercase string = " tolower(str)

}'

Lowercase string = hello, world !!!

### toupper(str)

[jerry]\$ awk 'BEGIN {
str = "hello, world !!!"

print "Uppercase string = " toupper(str)

}'

Uppercase string = HELLO, WORLD !!!

## 時間函數

AWK擁有的內置時間函數如下：

### systime

[jerry]\$ awk 'BEGIN {
print "Number of seconds since the Epoch = " systime()
}'

Number of seconds since the Epoch = 1418574432

### mktime(datespec)

[jerry]\$ awk 'BEGIN {
print "Number of seconds since the Epoch = " mktime("2014 12 14 30 20 10")
}'

Number of seconds since the Epoch = 1418604610

### strftime([format [, timestamp[, utc-flag]]])

[jerry]\$ awk 'BEGIN {
print strftime("Time = %m/%d/%Y %H:%M:%S", systime())
}'

Time = 12/14/2014 22:08:42

%a

The locale’s abbreviated weekday name.

%A

The locale’s full weekday name.

%b

The locale’s abbreviated month name.

%B

The locale’s full month name.

%c

The locale’s appropriate date and time representation. (This is %A %B %d %T %Y in the C locale.)

%C

The century part of the current year. This is the year divided by 100 and truncated to the next lower integer.

%d

The day of the month as a decimal number (01–31).

%D

Equivalent to specifying %m/%d/%y.

%e

The day of the month, padded with a space if it is only one digit.

%F

Equivalent to specifying %Y-%m-%d. This is the ISO 8601 date format.

%g

The year modulo 100 of the ISO 8601 week number, as a decimal number (00–99). For example, January 1, 1993 is in week 53 of 1992. Thus, the year of its ISO 8601 week number is 1992, even though its year is 1993. Similarly, December 31, 1973 is in week 1 of 1974. Thus, the year of its ISO week number is 1974, even though its year is 1973.

%G

The full year of the ISO week number, as a decimal number.

%h

Equivalent to %b.

%H

The hour (24-hour clock) as a decimal number (00–23).

%I

The hour (12-hour clock) as a decimal number (01–12).

%j

The day of the year as a decimal number (001–366).

%m

The month as a decimal number (01–12).

%M

The minute as a decimal number (00–59).

%n

A newline character (ASCII LF).

%p

The locale’s equivalent of the AM/PM designations associated with a 12-hour clock.

%r

The locale’s 12-hour clock time. (This is %I:%M:%S %p in the C locale.)

%R

Equivalent to specifying %H:%M.

%S

The second as a decimal number (00–60).

%t

A TAB character.

%T

Equivalent to specifying %H:%M:%S.

%u

The weekday as a decimal number (1–7). Monday is day one.

%U

The week number of the year (the first Sunday as the first day of week one) as a decimal number (00–53).

%V

The week number of the year (the first Monday as the first day of week one) as a decimal number (01–53).

%w

The weekday as a decimal number (0–6). Sunday is day zero.

%W

The week number of the year (the first Monday as the first day of week one) as a decimal number (00–53).

%x

The locale’s appropriate date representation. (This is %A %B %d %Y in the C locale.)

%X

The locale’s appropriate time representation. (This is %T in the C locale.)

%y

The year modulo 100 as a decimal number (00–99).

%Y

The full year as a decimal number (e.g. 2011).

%z

The time-zone offset in a +HHMM format (e.g., the format necessary to produce RFC 822/RFC 1036 date headers).

%Z

The time zone name or abbreviation; no characters if no time zone is determinable.

## 位操作函數

AWK具有以下內置位操作功能：

### and

[jerry]\$ awk 'BEGIN {
num1 = 10
num2 = 6

printf "(%d AND %d) = %d\\n", num1, num2, and(num1, num2)

}'

(10 AND 6) = 2

### compl

[jerry]\$ awk 'BEGIN {
num1 = 10

printf "compl(%d) = %d\\n", num1, compl(num1)

}'

compl(10) = 9007199254740981

### lshift

[jerry]\$ awk 'BEGIN {
num1 = 10

printf "lshift(%d) by 1 = %d\\n", num1, lshift(num1, 1)

}'

lshift(10) by 1 = 20

### rshift

[jerry]\$ awk 'BEGIN {
num1 = 10

printf "rshift(%d) by 1 = %d\\n", num1, rshift(num1, 1)

}'

rshift(10) by 1 = 5

### or

[jerry]\$ awk 'BEGIN {
num1 = 10
num2 = 6

printf "(%d OR %d) = %d\\n", num1, num2, or(num1, num2)

}'

(10 OR 6) = 14

### xor

[jerry]\$ awk 'BEGIN {
num1 = 10
num2 = 6

printf "(%d XOR %d) = %d\\n", num1, num2, xor(num1, num2)

}'

(10 bitwise xor 6) = 12

## 其它函數

AWK具有以下輔助功能：

### close(expr)

[jerry]\$ awk 'BEGIN {
cmd = "tr [a-z] [A-Z]"
print "hello, world !!!" |& cmd
close(cmd, "to")
cmd |& getline out
print out;
close(cmd);
}'

HELLO, WORLD !!!

### delete

[jerry]\$ awk 'BEGIN {
arr[0] = "One"
arr[1] = "Two"
arr[2] = "Three"
arr[3] = "Four"

print "Array elements before delete operation:"
for (i in arr) {
print arr\[i\]
}

delete arr\[0\]
delete arr\[1\]

print "Array elements after delete operation:"
for (i in arr) {
print arr\[i\]
}

}'

Array elements before delete operation:
One
Two
Three
Four

Array elements after delete operation:
Three
Four

### exit

[jerry]\$ awk 'BEGIN {
print "Hello, World !!!"

exit 10

print "AWK never executes this statement."

}'

Hello, World !!!

### fflush

fflush([output-expr])

### getline

[jerry]\$ awk '{getline; print \$0}' marks.txt

1. Rahul Maths 90
2. Kedar English 85
3. Hari History 89

### next

next函數改變程序流程。它會導致模式空間的當前處理停止。程序讀取下一行，並開始使用新的行再次執行的命令。例如下面的程序模式匹配成功時不執行任何處理。

[jerry]\$ awk '{if (\$0 ~/Shyam/) next; print \$0}' marks.txt

1. Amit Physics 80
2. Rahul Maths 90
3. Kedar English 85
4. Hari History 89

### nextfile

nextfile函數改變程序流。它停止處理當前輸入的文件，並通過模式/程序語句啓動新的週期，下一個文件的第一條記錄開始。比如下面的例子模式匹配成功時將停止第一個文件的處理。

file1:str1
file1:str2
file1:str3
file1:str4

file2.txt內容看起來如下：

file2:str1
file2:str2
file2:str3
file2:str4

[jerry]\$ awk '{ if (\$0 ~ /file1:str2/) nextfile; print \$0 }' file1.txt file2.txt

file1:str1
file2:str1
file2:str2
file2:str3
file2:str4

### return

function addition(num1, num2)
{
result = num1 + num2

return result

}

BEGIN {
res = addition(10, 20)
print "10 + 20 = " res
}

10 + 20 = 30

### system

[jerry]\$ awk 'BEGIN { ret = system("date"); print "Return value = " ret }'

Sun Dec 21 23:16:07 IST 2014
Return value = 0