cat>1.txt
2012-3-1 a hello
2012-3-2 b world
2012-3-3 c li72
2012-3-4 d xuhui
2012-3-5 a kugou
2012-3-6 b weipin
2012-3-7 c guangfa
1 输出 1.txt 的内容 $0 代表所有的一行内容 默认的输入和输出的分隔符都是回车,保存在内建变量ORS和RS中。
awk '{print $0}' 1.txt
2012-3-1 a hello
2012-3-2 b world
2012-3-3 c li72
2012-3-4 d xuhui
2012-3-5 a kugou
2012-3-6 b weipin
2012-3-7 c guangfa
2 输出并显示 行号 默认情况下以空格或tab分隔
awk '{print NR,$0}' 1.txt
3 输出一行中的第一个 和第三个
awk '{print $1,$3}' 1.txt
4 自定义分隔符为;
cat>2.txt
2012-3-1:a:hello
2012-3-2:b:world
2012-3-3:c:li72
2012-3-4:d:xuhui
2012-3-5:a:kugou
2012-3-6:b:weipin
2012-3-7:c:guangfa
以冒号分隔 输出1 和3 列
awk -F: '{print $1,$3}' 2.txt
可以同时使用多个域分隔符,这时应该把分隔符写成放到方括号中,如$awk -F'[:\t]' '{print $1,$3}' 2.txt,表示以空格、冒号和tab作为分隔符。
4 正则表达
用来在记录或者域内匹配正则表达式。如$ awk '$1 ~/^root/' 3.txt 将显示1.txt文件第一列中以root开头的行。
cat>3.txt
hroot.txt
root.txt
hello.txt
admin.txt
5 逻辑判断
例如:$ awk '{max = $1 > $3 $1: $3: print max}' 4.txt 。如果第一个域大于第三个域,$1就赋值给max,否则$3就赋值给max。
cat>4.txt
2 3 4
7 4 5
8 4 9
8 4 5
1 3 4
9 3 5
awk '$1 + $2 < 7' 4.txt 如果第一和第二个域相加大于7 ,则打印这些行。
awk '$1 > 5 && $2 < 10' 4.txt ,如果第一个域大于5,并且第二个域小于10,则打印这些行。
6 范围模板
范围模板匹配从第一个模板的第一次出现到第二个模板的第一次出现之间所有行。如果有一个模板没出现,
则匹配到开头或末尾。
如$ awk '/root/,/mysql/' 5.txt
将显示root第一次出现到mysql第一次出现之间的所有行。
cat>5.txt
lei
root
li72
1.txt
zpc
hello
mysql
cat 5.txt | awk '/root/,/mysql/'
13. 几个实例
$ awk '/^(no|so)/' 1.txt-----打印所有以模式no或so开头的行。
$ awk '/^[ns]/{print $1}' 1.txt-----如果记录以n或s开头,就打印这个记录。
$ awk '$1 ~/[0-9][0-9]$/(print $1}' 1.txt-----如果第一个域以两个数字结束就打印这个记录。
$ awk '$1 == 100 || $2 < 50' 1.txt-----如果第一个或等于100或者第二个域小于50,则打印该行。
$ awk '$1 != 10' 1.txt-----如果第一个域不等于10就打印该行。
$ awk '/1.txt/{print $1 + 10}' 1.txt-----如果记录包含正则表达式1.txt,则第一个域加10并打印出来。
$ awk '{print ($1 > 5 "ok "$1: "error"$1)}' 1.txt-----如果第一个域大于5则打印问号后面的表达式值,否则打印冒号后面的表达式值。
$ awk '/^root/,/^mysql/' 1.txt----打印以正则表达式root开头的记录到以正则表达式mysql开头的记录范围内的所有记录。
如果找到一个新的正则表达式root开头的记录,则继续打印直到下一个以正则表达式mysql开头的记录为止,或到文件末尾。
$ awk '$1 ~/7/{count = $2 + $3; print count}' 4.txt,上式的作用是,awk先扫描第一个域,一旦test匹配,
就把第二个域的值加上第三个域的值,并把结果赋值给变量count,最后打印出来。
awk可使用shell的重定向符进行重定向输出,
如:$ awk '$1 = 7 {print $1 > "output_file" }' 4.txt
上式表示如果第一个域的值等于100,
则把它输出到output_file中。也可以用>>来重定向输出,但不清空文件,只做追加操作。
awk '{print $1}' $file | sort | uniq -c | sort -k1nr | head -n$100 order.log
awk '{print $1}' $file | sort | uniq -c | sort -k1nr | head -n$3 log.log
awk '{print $1}' $file | sort log.log
awk '{print $1}' $file | sort | uniq -c log.log
awk '{print $1}' $file | sort | uniq -c | sort -k1nr log.log
awk '{print $1}' $file | sort | uniq -c | sort -k1nr | head -n$100 log.log
循环
awk '{ i = 1; while ( i <= NF ) { print NF,$i; i++}}' 4.txt
$ awk '{ sub(/test/, "mytest"); print }' output_file
$ awk '{ sub(/test/, "mytest"); $1}; print }' output_file
第一个例子在整个记录中匹配,替换只发生在第一次匹配发生的时候。如要在整个文件中进行匹配需要用到gsub
第二个例子在整个记录的第一个域中进行匹配,替换只发生在第一次匹配发生的时候。
$ awk '{ gsub(/test/, "mytest"); print }' output_file
$ awk '{ gsub(/test/, "mytest"), $1 }; print }' output_file
awk '{ print length }' 1.txt
awk '{ print substr( "hello world", 7,11 ) }'
awk '{ print toupper("test"), tolower("TEST") }'
awk '{printf("%s,",$1)}' 5.txt
2012-3-1 a hello
2012-3-2 b world
2012-3-3 c li72
2012-3-4 d xuhui
2012-3-5 a kugou
2012-3-6 b weipin
2012-3-7 c guangfa
1 输出 1.txt 的内容 $0 代表所有的一行内容 默认的输入和输出的分隔符都是回车,保存在内建变量ORS和RS中。
awk '{print $0}' 1.txt
2012-3-1 a hello
2012-3-2 b world
2012-3-3 c li72
2012-3-4 d xuhui
2012-3-5 a kugou
2012-3-6 b weipin
2012-3-7 c guangfa
2 输出并显示 行号 默认情况下以空格或tab分隔
awk '{print NR,$0}' 1.txt
3 输出一行中的第一个 和第三个
awk '{print $1,$3}' 1.txt
4 自定义分隔符为;
cat>2.txt
2012-3-1:a:hello
2012-3-2:b:world
2012-3-3:c:li72
2012-3-4:d:xuhui
2012-3-5:a:kugou
2012-3-6:b:weipin
2012-3-7:c:guangfa
以冒号分隔 输出1 和3 列
awk -F: '{print $1,$3}' 2.txt
可以同时使用多个域分隔符,这时应该把分隔符写成放到方括号中,如$awk -F'[:\t]' '{print $1,$3}' 2.txt,表示以空格、冒号和tab作为分隔符。
4 正则表达
用来在记录或者域内匹配正则表达式。如$ awk '$1 ~/^root/' 3.txt 将显示1.txt文件第一列中以root开头的行。
cat>3.txt
hroot.txt
root.txt
hello.txt
admin.txt
5 逻辑判断
例如:$ awk '{max = $1 > $3 $1: $3: print max}' 4.txt 。如果第一个域大于第三个域,$1就赋值给max,否则$3就赋值给max。
cat>4.txt
2 3 4
7 4 5
8 4 9
8 4 5
1 3 4
9 3 5
awk '$1 + $2 < 7' 4.txt 如果第一和第二个域相加大于7 ,则打印这些行。
awk '$1 > 5 && $2 < 10' 4.txt ,如果第一个域大于5,并且第二个域小于10,则打印这些行。
6 范围模板
范围模板匹配从第一个模板的第一次出现到第二个模板的第一次出现之间所有行。如果有一个模板没出现,
则匹配到开头或末尾。
如$ awk '/root/,/mysql/' 5.txt
将显示root第一次出现到mysql第一次出现之间的所有行。
cat>5.txt
lei
root
li72
1.txt
zpc
hello
mysql
cat 5.txt | awk '/root/,/mysql/'
13. 几个实例
$ awk '/^(no|so)/' 1.txt-----打印所有以模式no或so开头的行。
$ awk '/^[ns]/{print $1}' 1.txt-----如果记录以n或s开头,就打印这个记录。
$ awk '$1 ~/[0-9][0-9]$/(print $1}' 1.txt-----如果第一个域以两个数字结束就打印这个记录。
$ awk '$1 == 100 || $2 < 50' 1.txt-----如果第一个或等于100或者第二个域小于50,则打印该行。
$ awk '$1 != 10' 1.txt-----如果第一个域不等于10就打印该行。
$ awk '/1.txt/{print $1 + 10}' 1.txt-----如果记录包含正则表达式1.txt,则第一个域加10并打印出来。
$ awk '{print ($1 > 5 "ok "$1: "error"$1)}' 1.txt-----如果第一个域大于5则打印问号后面的表达式值,否则打印冒号后面的表达式值。
$ awk '/^root/,/^mysql/' 1.txt----打印以正则表达式root开头的记录到以正则表达式mysql开头的记录范围内的所有记录。
如果找到一个新的正则表达式root开头的记录,则继续打印直到下一个以正则表达式mysql开头的记录为止,或到文件末尾。
$ awk '$1 ~/7/{count = $2 + $3; print count}' 4.txt,上式的作用是,awk先扫描第一个域,一旦test匹配,
就把第二个域的值加上第三个域的值,并把结果赋值给变量count,最后打印出来。
awk可使用shell的重定向符进行重定向输出,
如:$ awk '$1 = 7 {print $1 > "output_file" }' 4.txt
上式表示如果第一个域的值等于100,
则把它输出到output_file中。也可以用>>来重定向输出,但不清空文件,只做追加操作。
awk '{print $1}' $file | sort | uniq -c | sort -k1nr | head -n$100 order.log
awk '{print $1}' $file | sort | uniq -c | sort -k1nr | head -n$3 log.log
awk '{print $1}' $file | sort log.log
awk '{print $1}' $file | sort | uniq -c log.log
awk '{print $1}' $file | sort | uniq -c | sort -k1nr log.log
awk '{print $1}' $file | sort | uniq -c | sort -k1nr | head -n$100 log.log
循环
awk '{ i = 1; while ( i <= NF ) { print NF,$i; i++}}' 4.txt
$ awk '{ sub(/test/, "mytest"); print }' output_file
$ awk '{ sub(/test/, "mytest"); $1}; print }' output_file
第一个例子在整个记录中匹配,替换只发生在第一次匹配发生的时候。如要在整个文件中进行匹配需要用到gsub
第二个例子在整个记录的第一个域中进行匹配,替换只发生在第一次匹配发生的时候。
$ awk '{ gsub(/test/, "mytest"); print }' output_file
$ awk '{ gsub(/test/, "mytest"), $1 }; print }' output_file
awk '{ print length }' 1.txt
awk '{ print substr( "hello world", 7,11 ) }'
awk '{ print toupper("test"), tolower("TEST") }'
awk '{printf("%s,",$1)}' 5.txt