AWK內置函數
AWK許多內置函數,隨時可爲程序員使用。本教程介紹了AWK的算術,字符串,時間,位操作和其他雜項函數的例子:
算術函數
AWK具有以下內置的算術函數:
atan2(y, x)
它返回弧度的反正切(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)
此函數返回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)
這個函數截斷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
該函數返回一個隨機數N,在0和1之間,使得0<= N <1。例如下面的例子會產生三個隨機數:
[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)
此函數返回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)
該函數返回expr的平方根。
[jerry]$ awk 'BEGIN {
param = 1024.0
result = sqrt(param)
printf "sqrt(%f) = %f\n", param, result
}'
在執行上面的代碼後,得到以下結果:
sqrt(1024.000000) = 32.000000
srand([expr])
這個函數使用產生種子值的隨機數。它使用expr作爲隨機數生成的新的種子。如果沒有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] ])
這個函數排序arr,使用gawk的常規規則比較值的內容,並替換排序值的索引常用使用連續整數是從1開始。
[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] ])
此函數的行爲類似於asort(),所不同的是數組索引用於排序。
[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)
它檢查sub是否是str的子字符串。如果成功則返回sub開始位置,否則返回0。str第一個字符的位置是1。
[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)
它返回正則表達式的字符串str第一個最長的匹配索引。如果沒有找到匹配返回0。
[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)
這個函數分割字符串str爲正則表達式regex字段,字段被加載到數組arr。如果省略regex那麼fs被使用。
[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)
該函數返回按照expr-list格式構造一個字符串。
[jerry]$ awk 'BEGIN {
str = sprintf("%s", "Hello, World !!!")
print str
}'
在執行上面的代碼後,得到以下結果:
Hello, World !!!
strtonum(str)
這個函數檢查str並返回它的數值。如果str以0開始,把它當作一個八進制數。如果str開頭是0x或0X,那麼它當作一個十六進制數。否則,假設它是一個十進制數。
[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)
這個函數執行單一的替代。它用正則表達式子第一次出現。第三個參數是可選的,如果它被刪去,$0被使用。
[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)
該函數返回字符串str的子字符串,起始於長度l爲索引開始。如果省略長度,則返回str的後綴爲索引起始。
[jerry]$ awk 'BEGIN {
str = "Hello, World !!!"
subs = substr(str, 1, 5)
print "Substring = " subs
}'
在執行上面的代碼後,得到以下結果:
Substring = Hello
tolower(str)
該函數返回字符串str具有轉換爲小寫全部大寫字符的副本。
[jerry]$ awk 'BEGIN {
str = "HELLO, WORLD !!!"
print "Lowercase string = " tolower(str)
}'
在執行上面的代碼後,得到以下結果:
Lowercase string = hello, world !!!
toupper(str)
該函數返回字符串str具有轉換爲大寫小寫字符的副本。
[jerry]$ awk 'BEGIN {
str = "hello, world !!!"
print "Uppercase string = " toupper(str)
}'
在執行上面的代碼後,得到以下結果:
Uppercase string = HELLO, WORLD !!!
時間函數
AWK擁有的內置時間函數如下:
systime
該函數返回當天的當前時間以來的大紀元(1970-01-0100:00:00 UTC在POSIX系統)的秒數。
[jerry]$ awk 'BEGIN {
print "Number of seconds since the Epoch = " systime()
}'
在執行上面的代碼後,得到以下結果:
Number of seconds since the Epoch = 1418574432
mktime(datespec)
返回由systime()這個函數轉換的timespec字符串進入相同的形式的時間標記。所述的timespec形式如YYYY MM DD HH MM SS的字符串。
[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
以下是由AWK支持的各種時間格式:
日期格式規範
描述
%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 !!!
讓我們來看看下面的腳本解釋:
第一條語句,cmd = "tr [a-z] [A-Z]" -是要從AWK建立雙向通信的命令。
下一個語句即打印命令,提供輸入到tr命令。此處&|指示雙向通信。
第三個語句,即close- 關閉完成後執行處理。
接下來語句cmd |& getline函數輸出到出變量,在函數getline函數的幫助下。
接下來print語句打印輸出,並最終close函數關閉命令。
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
這個函數停止腳本的執行。它也接受一個可選的expr變成AWK的返回值。下面的例子說明了exit函數的用法。
[jerry]$ awk 'BEGIN {
print "Hello, World !!!"
exit 10
print "AWK never executes this statement."
}'
在執行上面的代碼後,得到以下結果:
Hello, World !!!
fflush
這個函數用於清空打開輸出文件或管道相關的緩衝區。下面是函數的語法。
fflush([output-expr])
如果沒有提供output-expr,它清空標準輸出。如果輸出expr爲空字符串(「」),則清空所有打開的文件和管道。
getline
這個函數指示AWK讀取下一行。下面的例子讀取和使用getline函數的顯示marks.txt文件的內容。
[jerry]$ awk '{getline; print $0}' marks.txt
在執行上面的代碼後,得到以下結果:
- Rahul Maths 90
- Kedar English 85
- Hari History 89
我們來一步一步解釋以上代碼:
在開始時,AWK從marks.txt文件讀取第一行並將其存儲到$0變量。
在接下來的語句,指示AWK使用函數getline讀取下一行。因此AWK讀取第二行,並將其存儲到$0變量。
最後AWK的print語句打印第二行。這個過程繼續,直到文件內容被讀取完。
next
next函數改變程序流程。它會導致模式空間的當前處理停止。程序讀取下一行,並開始使用新的行再次執行的命令。例如下面的程序模式匹配成功時不執行任何處理。
[jerry]$ awk '{if ($0 ~/Shyam/) next; print $0}' marks.txt
在執行上面的代碼後,得到以下結果:
- Amit Physics 80
- Rahul Maths 90
- Kedar English 85
- Hari History 89
nextfile
nextfile函數改變程序流。它停止處理當前輸入的文件,並通過模式/程序語句啓動新的週期,下一個文件的第一條記錄開始。比如下面的例子模式匹配成功時將停止第一個文件的處理。
首先,創建兩個文件。file1.txt內容看起來如下:
file1:str1
file1:str2
file1:str3
file1:str4
file2.txt內容看起來如下:
file2:str1
file2:str2
file2:str3
file2:str4
現在,讓我們使用nextfile函數:
[jerry]$ awk '{ if ($0 ~ /file1:str2/) nextfile; print $0 }' file1.txt file2.txt
在執行上面的代碼後,得到以下結果:
file1:str1
file2:str1
file2:str2
file2:str3
file2:str4
return
這個函數可以在用戶定義函數內使用以返回該值。請注意,函數的返回值是不確定的,如果沒有提供expr 。下面的例子說明了return函數的使用。
首先,創建一個包含AWK命令functions.awk文件,如下所示:
function addition(num1, num2)
{
result = num1 + num2
return result
}
BEGIN {
res = addition(10, 20)
print "10 + 20 = " res
}
在執行上面的代碼後,得到以下結果:
10 + 20 = 30
system
這個函數執行指定的命令,並返回它的退出狀態。返回狀態0表示命令執行成功。非零值表示命令執行的故障。例如下面的例子顯示當前日期以及也顯示命令的返回狀態。
[jerry]$ awk 'BEGIN { ret = system("date"); print "Return value = " ret }'
在執行上面的代碼後,得到以下結果:
Sun Dec 21 23:16:07 IST 2014
Return value = 0