简单使用:
awk :
对于文件中一行行的独处来执行操作 。
使用‘:’来分割这一行,把这一行的第一第四个域打印出来 。
1 | awk -F :'{print $1,$4}' |
详细介绍:
AWK命令介绍 awk语言的最基本功能是在文件或字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作,完整的awk脚本通常用来格式化文本文件中的信息
1. 调用awk:
第一种命令行方式,如: awk [-Field-separator] 'commands' input-file(s)
这里commands是真正的awk命令,[-F域分隔符]是可选的,awk默认使用空格分隔,因此如果要浏览域间有空格的文本,不必指定这个选项,但如果浏览如passwd文件,此文件各域使用冒号作为分隔符,则必须使用-F选项: awk -F : 'commands' input-file
第二种,将所有awk命令插入一个文件,并使awk程序可执行,然后用awk命令解释器作为脚本的首行,以便通过键入脚本名称来调用它 第三种,将所有awk命令插入一个单独文件,然后调用,如:
1 | awk -f awk-script-file input-file |
awk ‘{print $0}’ temp.txt > sav.txt
1 | 表示打印所有域并把结果重定向到sav.txt中 |
awk ‘{print $0}’ temp.txt|tee sav.txt
1 | 和上例相似,不同的是将在屏幕上显示出来 |
awk ‘{print $1,$4}’ temp.txt
1 | 只打印出第1和第4域 |
awk ‘BEGIN {print “NAME GRADE\n—-“} {print $1”\t”$4}’ temp.txt
1 | 表示打信息头,即输入的内容的第一行前加上"NAME GRADE\\n-------------",同时内容以tab分开 |
awk ‘BEGIN {print “being”} {print $1} END {print “end”}’ temp
1 | 同时打印信息头和信息尾 |
awk ‘{name=$1;six=$3; if (six==”man”) print name “ is “ six}’ temp
1 | 域值比较操作: |
awk ‘BEGIN {BASE=”27”} {if ($4<BASE) print $0}’ temp
1 | 修改数值域取值:(原输入文件不会被改变) |
awk ‘{if ($1==”asima”) $6=$6-1;print $1,$6,$7}’ temp
1 | 修改文本域: |
awk ‘{if ($1==”asima) ($1==”desc”);print $1}’ temp
1 | 只显示修改记录:(只显示所需要的,区别上一条命令,注意{}) |
awk ‘{if ($1==”asima) {$1==”desc”;print$1}}’ temp
1 | 创建新的输出域: |
awk ‘{$4=$3-$2; print $4}’ temp
1 | 统计列值: |
1 | awk '{(tot+=$3)};END {print tot}' temp #只显示最后的结果 |
文件长度相加:
1 | ls -l|awk '/^\[^d\]/ {print $9"\\t"$5} {tot+=$5} END{print "totKB:" tot}' |
ls -l|awk ‘{print $9}’ #常规情况文件名是第9域
1 |
|
echo “65” |awk ‘{printf “%c\n”,$0}’ #输出A
1 | ``` |
awk ‘{printf “%-15s %s\n”,$1,$3}’ temp
将第一个域全部左对齐显示
1 | 2.8. 其他awk用法: |
awk ‘{if ($5<AGE) print $0}’ AGE=10 temp
who | awk ‘{if ($1==user) print $1 “ are in “ $2 ‘ user=$LOGNAME #使用环境变量
```
awk脚本命令:
开头使用 !/bin/awk -f
,如果没有这句话自含脚本将不能执行,例子:
!/bin/awk -f
# all comment lines must start with a hash '#'
# name: student_tot.awk
# to call: student_tot.awk grade.txt
# prints total and average of club student points
# print a header first
BEGIN
{
print "Student Date Member No. Grade Age Points Max"
print "Name Joined Gained Point Available"
print"========================================================="
}
# let's add the scores of points gained
(tot+=$6);
# finished processing now let's print the total and average point
END
{
print "Club student total points :" tot
print "Average Club Student points :" tot/N
}
2.9. awk数组:
awk的循环基本结构
For (element in array) print array\[element\]
awk 'BEGIN {record="123#456#789";split(record,myarray,"#")}
END { for (i in myarray) {print myarray\[i\]} }
3.0 awk中自定义语句
一.条件判断语句(if) if(表达式) #if ( Variable in Array ) 语句1 else 语句2 格式中”语句1”可以是多个语句,如果你为了方便Unix awk判断也方便你自已阅读,你最好将多个语句用{}括起来。Unix awk分枝结构允许嵌套,其格式为: if(表达式) {语句1} else if(表达式) {语句2} else {语句3}
[chengmo@localhost nginx\]# awk 'BEGIN{
test=100;
if(test>90)
{
print "very good";
}
else if(test>60)
{
print "good";
}
else
{
print "no pass";
}
}'
very good
每条命令语句后面可以用“;”号结尾。
二.循环语句(while,for,do)
1.while语句 格式: while(表达式) {语句} 例子:
[chengmo@localhost nginx\]# awk 'BEGIN{
test=100;
total=0;
while(i<=test) 5050 { total+="i;" i++; } print total; }' < code>=test)>
2.for 循环
for循环有两种格式:
格式1: for(变量 in 数组) {语句} 例子:
[chengmo@localhost nginx\]# awk 'BEGIN{
for(k in ENVIRON)
{
print k"="ENVIRON\[k\];
}
}'
AWKPATH=.:/usr/share/awk
OLDPWD=/home/web97
SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass
SELINUX\_LEVEL\_REQUESTED=
SELINUX\_ROLE\_REQUESTED=
LANG=zh_CN.GB2312
。。。。。。 说明:ENVIRON 是awk常量,是子典型数组。
格式2: for(变量;条件;表达式) {语句} 例子:
[chengmo@localhost nginx\]# awk 'BEGIN{ total=0; for(i=0;i<=100;i++) 5050 { total+="i;" } print total; }' < pre>=100;i++)>
3.do循环
格式: do {语句}while(条件) 例子:[chengmo@localhost nginx\]# awk 'BEGIN{ total=0; i=0; do { total+=i; i++; }while(i<=100) 5050 print total; }' < code>=100)>
以上为awk流程控制语句,从语法上面大家可以看到,与c语言是一样的。
有了这些语句,其实很多shell程序都可以交给awk,而且性能是非常快的。
break 当 break 语句用于 while 或 for 语句时,导致退出程序循环。
continue 当 continue 语句用于 while 或 for 语句时,使程序循环移动到下一个迭代。
next 能能够导致读入下一个输入行,并返回到脚本的顶部。这可以避免对当前输入行执行其他的操作过程。
exit 语句使主输入循环退出并将控制转移到END,如果END存在的话。如果没有定义END规则,或在END中应用exit语句,则终止脚本的执行。
NR与FNR: QUOTE:
A.awk对多输入文件的执行顺序是,先将代码作用于第一个文件(一行行读入),然后该重复的代码又作用于第二个文件,再作用于第三个文件。
B.awk对多输入文件的执行顺序产生了行序号的问题。当第一个文件执行完,下次读入第二个文件,那么第二个文件的第一行怎么算呢?
如果又计为1的话,那不就两个1了么?
(因为第一个文件也有第一行)。这就是NR和FNR的问题。
NR :全局行数(第二个文件的第一行接着第一个文件尾行数顺序计数)
FNR:当前文件自身的行数(不考虑前几个输入文件的自身行数及总数)
例如:data1.txt中有40行,data2.txt中有50行,那么awk ‘{}’ data1.txt data2.txt NR 的值依次为:1,2……40,41,42……90
FNR的值依次为:1,2……40, 1, 2……50
getline函数说明: awk 的 getline语句用于简单地读取一条记录。
如果用户有一个数据记录类似两个物理记录,那么getline将尤其有用。它完成一般字段的分离(设置字段变量$0 FNR NF NR)。
如果成功则返回1,失败则返回0(到达文件尾)。
QUOTE: A.getline从整体上来说,应这么理解它的用法: 当其左右无重定向符 | 或 < 时,getline作用于当前文件,读入当前文件的第一行给其后跟的变量 var 或$0(无变量);应该注意到,由于awk在处理getline之前已经读入了一行,所以getline得到 的返回结果是隔行的。
当其左右有重定向符 | 或 < 时,getline则作用于定向输入文件,由于该文件是刚打开,并没有被 awk读入一行,只是getline读入,那么getline返回的是该文件的第一行,而不是隔行。
B.getline用法大致可分为三大类(每大类又分两小类),即总共有6种用法。代码如下:
QUOTE:
nawk ‘BEGIN{“cat data.txt”|getline d; print d}’ data2.txt
nawk ‘BEGIN{“cat data.txt”|getline; print $0}’ data2.txt
nawk ‘BEGIN{getline d < “data.txt”; print d}’ data2.txt
nawk ‘BEGIN{getline < “data.txt”; print $0}’ data2.txt
以上四行代码均实现“只打印data.txt文件的第一行”(若打印全部行,用循环 )
eg. nawk ‘BEGIN{FS=”:”;while(getline<” etc passwd”>0){print $1}}’ data.txt ”>
QUOTE:
nawk ‘{getline d; print d”#”$3}’ data.txt
awk首先读入第一行,接着处理getline函数,然后把下一行指定给变量d,再先打印d,由于d后面有换行符,所以后面紧跟的#会覆盖d,后面的$3同样也会覆盖d。 QUOTE:
nawk ‘{getline; print $0”#”$3}’ data.txt
awk首先读入第一行接着处理getline函数,然后把下一行指定给$0,现在的$0已经是下一行内容,后面的#和$3(从$0中取)会覆盖$0的内容。 在awk中,有时需要调用系统工具来完成awk不擅长的工作,awk提供的system命令可以用来执行,但收不到外部工具的输出结果。好在可以运用getline来满足这个需求。例如
test.awk:
{
datecommand="/bin/date -j -f \"%d/%b/%Y:%H:%M:%S\" " $olddatestr " \"+%Y%m%d %H%M%S\"";
datecommand | getline newdatestr
close(datecommand);
}
外部命令需要awk占用一个文件描述符,而awk最多能打开的文件有一个上限,而且不大(比如说16),所以最后做一个close是好习惯。把命令串定义为一个变量也是为了close的时候方便