11.1 awk入门
awk是一种非常强大的数据处理工具,其本身可以称为是一种程序设计语言,因而具有其他程序设计语言所共同拥有的一些特征,例如变量、函数以及表达式等。通过awk,用户可以编写一些非常实用的文本处理工具。本节将介绍awk的基础知识。
11.1.1 awk的功能
awk是Linux以及UNIX环境中现有的功能最强大的数据处理工具。简单地讲,awk是一种处理文本数据的编程语言。awk的设计使得它非常适合于处理由行和列组成的文本数据。而在Linux或者UNIX环境中,这种类型的数据是非常普遍的。
除此之外,awk还是一种编程语言环境,它提供了正则表达式的匹配,流程控制,运算符,表达式,变量以及函数等一系列的程序设计语言所具备的特性。它从C语言等中获取了一些优秀的思想。awk程序可以读取文本文件,对数据进行排序,对其中的数值执行计算已经生成报表等。
11.1.2 awk命令的基本语法
awk命令的基本语法如下:
awk pattern { actions }
在上面的语法中,pattern表示匹配模式,actions表示要执行的操作。以上语法表示,当某个文本行符合pattern指定的匹配规则时,执行actions所执行的操作。在上面的语法中,pattern和actions都是可选的,但是两者必须保证至少有一个。如果省略匹配模式pattern,则表示对所有的文本行执行actions所表示的操作;如果省略actions,则表示将匹配成功的行输出到屏幕。
11.1.3 awk的工作流程
对于初学者来说,搞清楚awk的工作流程非常重要。只有在掌握了awk的工作流程之后,才有可能用好awk来处理数据。在awk处理数据时,它会反复执行以下4个步骤:
(1)自动从指定的数据文件中读取行文本。
(2)自动更新awk的内置系统变量的值,例如列数变量NF、行数变量NR、行变量$0以及各个列变量$1、$2等等。
(3)依次执行程序中所有的匹配模式及其操作。
(4)当执行完程序中所有的匹配模式及其操作之后,如果数据文件中仍然还有为读取的数据行,则返回到第(1)步,重复执行(1)~(4)的操作。
11.1.4 执行awk程序的几种方式
1.通过命令行执行awk程序,语法如下:
awk 'program-text' datafile
#输出所有的行
{ print }
2.执行awk脚本
在awk程序语句比较多的情况下,用户可以将所有的语句写在一个脚本文件中,然后通过awk命令来解释并执行其中的语句。awk调用脚本的语法如下:
awk -f program-file file ..
在上面的语法中,-f选项表示从脚本文件中读取awk程序语句,program-file表示awk脚本文件名称,file表示要处理的数据文件。
3.可执行脚本文件
在上面介绍的两种方式中,用户都需要输入awk命令才能执行程序。除此之外,用户还可以通过类似于Shell脚本的方式来执行awk程序。在这种方式中,需要在awk程序中指定命令解释器,并且赋予脚本文件的可执行权限。其中指定命令解释器的语法如下:
#!/bin/awk -f
以上语句必须位于脚本文件的第一行。然后用户就可以通过以下命令执行awk程序:
awk-script file
其中,awk-script为awk脚本文件名称,file为要处理的文本数据文件。
#! /bin/awk -f
#输出所有的行
{ print }
11.2 awk的模式匹配
在awk中,匹配模式处于非常重要的地位,它决定着匹配模式后面的操作会影响到哪些文本行。awk中的匹配模式主要包括关系表达式、正则表达式、混合模式,BEGIN模式以及END模式等,本节将对这些模式匹配进行详细地介绍。
11.2.1 关系表达式
awk提供了许多关系运算符,例如大于>、小于<或者等于==等,关于关系运算符的详细使用方法,将在第4节中详细介绍。awk允许用户使用关系表达式作为匹配模式,当某个文本行满足关系表达式时,将会执行相应的操作。
#! /bin/bash
#打印第2列的成绩超过80的行
result=`awk '$2 > 80 { print }' scores.txt`
echo "$result"
11.2.2 正则表达式
awk支持以正则表达式作为匹配模式,与sed一样,用户需要将正则表达式放在两条斜线之间,其基本语法如下:
/regular_expression/
#! /bin/bash
#输出以字符T开头的行
result=`awk '/^T/ { print }' scores.txt`
echo "$result"
#! /bin/bash
#输出以Tom或者Kon开头的行
result=`awk '/^(Tom|Kon)/ { print }' scores.txt`
echo "$result"
11.2.3 混合模式
awk不仅支持单个的关系表达式或者正则表达式作为模式,还支持使用逻辑运算符&&、||或者!将多个表达式组合起来作为一个模式。其中,&&表示逻辑与,||表示逻辑或,!表示逻辑非,关于这3个运算符的详细用法,将在第4节中介绍。
#! /bin/bash
#混合模式
result=`awk '/^K/ && $2 > 80 { print }' scores.txt`
echo "$result"
11.2.4 区间模式
awk还支持一种区间模式,也就是说通过模式可以匹配一段连续的文本行。区间模式的语法如下:
pattern1, pattern2
其中,pattern1和pattern2都是前面所讲的匹配模式,可以是关系表达式,也可以是正则表达式等。当然,也可以是这些模式的混合形式。
#! /bin/bash
#区间模式
result=`awk '/^Nancy/, $2==92 { print }' scores.txt`
echo "$result"
11.2.5 BEGIN模式
BEGIN模式是一种特殊的内置模式,其成立的时机为awk程序刚开始执行,但是又尚未读取任何数据之前。
因此,该模式所对应的操作仅仅被执行一次,当awk读取数据之后,BEGIN模式便不再成立。所以,用户可以将与数据文件无关,而且在整个程序的生命周期中,只需执行1次的代码放在BEGIN模式对应的操作中。
#! /bin/awk -f
#通过BEGIN模式输出字符串
BEGIN { print "Hello! World." }
#! /bin/awk -f
#通过BEGIN模式初始化变量
BEGIN {
FS="[\t:]"
RS="\n"
count=30
print "The report is about students's scores."
}
11.2.6 END模式
END模式是awk的另外一种特殊模式,该模式成立的时机与BEGIN模式恰好相反,它是在awk命令处理完所有的数据,即将退出程序时成立,在此之前,END模式并不成立。
无论数据文件中包含多少行数据,在整个程序的生命周期中,该模式所对应的操作只被执行1次。因此,一般情况下,用户可以将许多善后工作放在END模式对应的操作中。
#! /bin/awk -f
#输出报表头
BEGIN {
print "scores report"
print "================================="
}
#输出数据
{ print }
#报表完成
END {
print "================================"
print "printing is over"
}
11.3 变量
与其他的程序设计语言一样,awk本身支持变量的相关操作,包括变量的定义和引用,以及参与相关的运算等。此外,还包含了许多内置的系统变量。本节将介绍awk中的变量的相关知识。
11.3.1 变量的定义和引用
变量的作用是用来存储数据。变量由变量名和值两部分组成,其中变量名是用来实现变量值的引用的途径,而变量值则是内存空间中存储的用户数据。
awk的变量名只能包括字母、数字和下划线,并且不能以数字开头。例如abc、a_、_z以及a123都是合法的变量名,而123abc则是非法的变量名。另外,awk的变量名是区分大小写的,因此,X和x分别表示不同的变量。
在awk中定义变量的方法非常简单,只要给出一个变量名并且赋予适当的值即可。
awk中的变量类型分为两种,分别为字符串和数值。但是在定义awk变量时,毋需指定变量类型,awk会根据变量所处的环境自动判断。如果没有指定值,数值类型的变量的缺省值为0,字符串类型的变量的缺省值为空串。
#! /bin/awk -f
BEGIN {
#定义变量x
x=3
#定义变量message
message="Hello " "world"
#输出变量
print x
print message
}
11.3.2 系统内置变量
akw提供了许多非常实用的系统变量,例如字段变量、字段数变量以及记录数变量等。
变量 说明
$0 记录变量,表示当前记录
$n 字段变量,其中n为整数,且n>1,表示第n个字符的值
NF 整数值,表示当前记录的字段数
NR 整数值,表示awk已经读入的字段数
FILENAM 表示正在处理的数据文件的名称
RS 记录分隔(record seperator)字符,默认值是换行符
FS 字段分割(field seperator)字符,默认值是空格或者制表符
11.3.3 记录分隔符RS和字段分隔符FS
记录分隔符使用系统变量RS来指定,如果没有指定,则默认为换行符\n。在绝大部分的情况下,这种方式都是有效的,因为awk每次都是从数据文件中只读取一行数据进行处理。
所以正常情况下,一行数据就代表一条记录。但是,这并不意味着总是这样,有些数据文件中用多行文本来描述一条记录
#! /bin/awk -f
{
#输出每行数据
print "=========================================="
}
#! /bin/awk -f
BEGIN {
#定义记录分隔符
RS=""
}
{
print "=========================================="
}
#! /bin/awk -f
BEGIN {
#定义记录分隔符
RS=""
#定义字段分隔符
FS="\n"
}
#输出第1个字段
{ print $1 }
11.3.4 记录和字段的引用
在awk中,用户可以使用系统变量来引用数据文件中的记录和字段。
与关系型数据库不同,awk每次只是读取1行文本,因此,在awk程序中,所说的记录和字段的引用都是针对当前记录来说的。
变量$0表示正在读取的当前的记录,该变量将整个记录作为一个字符串来处理。
#! /bin/awk -f
#通过$0引用整个记录
{ print $0 }
#! /bin/awk -f
{
#输出第1个字段以及第2~5个字段的和
print $1, $2+$3+$4+$5
}
11.4 运算符和表达式
awk是一种编程语言环境,因此,它也支持常用的运算符以及表达式,例如算术运算、逻辑运算以及关系运算等。本节将对awk所支持的常用的运算符以及表达式进行介绍。
11.4.1 算术运算符
awk支持常用的算术运算,这一点与其他的程序设计语言基本相同
运算符 说明
+ 加法运算
- 减法运算
* 乘法运算
/ 除法运算
% 求模运算
^ 指数运算
#! /bin/awk -f
BEGIN {
#除法运算
x=5/2
print x
#求模运算
x=5%2
print x
#指数运算
x=2^3
print x
}
11.4.2 赋值运算符
= += -= *= /= %= ^=
#! /bin/awk -f
BEGIN {
#简单赋值
x=4
print x
#求和赋值
x+=10
print x
#乘积赋值
x*=2
print x
#幂运算赋值
x^=2
print x
}
11.4.3 条件运算符
awk中的条件运算符只有一个,其语法如下:
expression ? value1 : value2
这是一个三目运算符,当表达式expression的值为真时,返回值为value1;否则,返回值为value2。
#! /bin/awk -f
{
#如果大于90,输出A,否则输出B
grade=($2>90?"A":"B")
print grade
}
11.4.4 逻辑运算符
awk支持3种逻辑运算,分别为逻辑与(&&)、逻辑或(||)和逻辑非(!);
#! /bin/awk -f
#输出所有的字段的值都大于80的记录
$2 > 80 && $3 > 80 && $4 > 80 && $5 >80 {
}
11.4.5 关系运算符
awk支持常用的关系运算符,例如大于、小于以及等于;
#! /bin/awk -f
#匹配第1个字段以字符K开头的记录
$1 ~ /^K/ { print }
11.4.6 其他运算符
除了前面介绍的运算符之外,awk还支持其他的一些运算符,例如正号+、负号-、自增++以及自减--等。这些运算符的使用方法与其他的语言的使用方法完全相同,不再举例说明。
11.5 函数
awk提供函数的支持。awk本身提供了许多系统函数,例如字符串函数以及算术函数。另外,用户还可以自定义函数。由于自定义函数使用非常少,所以本节主要介绍awk提供的系统函数。
11.5.1 字符串函数
字符串是awk中的两大类型之一,awk提供了一些常见的字符串处理函数,例如index()、length()以及match()等,下表列出了常用的字符串函数。
index(string1, string2)
返回string2在string1中的位置;如果string1不包含string2则返回0;
length(string)
返回字符串string的长度;
match(string, regexp)
在字符串string中搜索符合正则表达式regexp的(第一个)子字符串,返回值体现在系统变量RSTART和RLENGTH中;
split(string, array, seperator)
根据指定的分隔符seperator,将字符串string分割成多个字段,并存储到array数组中;
sub(regexp, replacement, string)
将字符串string中的第1个符合正则表达式regexp的子字符串全部替换为replacement;
gsub(regexp, replacement, string)
将字符串string中的所有符合正则表达式regexp的子字符串全部替换为replacement;
substr(string, start, [length])
从字符串string中截取指定的字符串,起始位置为start,长度为length;如果省略length,则表示从start开始一直截取到字符串结束;
1.index(string1, string2)
该函数用来定位字符串string2在字符串string1中出现的位置。如果出现多次,则返回第1次出现的位置;如果string1不包含string2,则该函数返回0。该函数区分大小写,用户在使用时一定要注意。
#! /bin/awk -f
BEGIN {
#输出子串在父串中出现的位置
print index("Hello,world.","world")
}
2.length(string)
该函数的返回值为整数,表示字符串string的长度。
#! /bin/awk -f
BEGIN {
#输出字符串的长度
print length("Hello, world.")
}
3.match(string, regexp)
该函数的第1个参数为字符串,第2个参数为正则表达式,其功能是在字符串string中搜索匹配正则表达式的子串。
用户可以通过系统变量RSTART和RLENGTH来获取相关的返回值。
其中,
RSTART用来返回正则表达式匹配的子串在父串中出现的位置,如果匹配不成功,则返回0。
RLENGTH用来返回正则表达式匹配的子串的长度,如果匹配不成功,则返回-1。
#! /bin/awk -f
BEGIN {
#通过正则表达式搜索子串
match("Hello, world.",/o/)
print RSTART, RLENGTH
}
4.split(string,array,seperator)
该函数的功能是将一个字符串根据指定的分隔符拆分成一个数组。
其中第1个参数为要拆分的字符串,第2个参数是用来存储拆分结果的数组,第3个参数用来指定分隔符,分隔符可以使用正则表达式来表达。
#! /bin/awk -f
BEGIN {
string="5P12p89"
#使用分隔符P或者p分隔字符串
split(string,arr,/[Pp]/)
#输出第1~3个数组元素
print arr[1]
print arr[2]
print arr[3]
}
5.sub(regexp,replacement,string)和gsub(regexp,replacement,string)
这2个函数的作用都是替换字符串中的子串,其区别在于前者只替换第1次出现的子串,而后者则替换所有出现的子串。
这2个函数的参数完全相同,第1个参数为正则表达式,表示匹配规则。第2个参数为用来替换的字符串,第3个参数是将要被处理的字符串。
#! /bin/awk -f
BEGIN {
#定义字符串
string="abcd6b12abcabc212@123465"
#将第1个符合正则表达式/(abc)+[0-9]*/的子串用括号括起来
sub(/(abc)+[0-9]*/,"(&)",string)
print string
#将所有符合正则表达式/(abc)+[0-9]*/的子串用括号括起来
gsub(/(abc)+[0-9]*/,"(&)",string)
print string
}
6.substr(string,start,[length])
该函数的功能是截取指定长度的子串。
第1个参数为父串,第2个参数表示子串开始截取的位置,第3个参数表示要截取的长度。其中,第3个参数可以省略,如果省略了该参数,则表示从start参数指定的位置开始,一直截取到父串的末尾。
通过match()函数和substr()函数,用户可以将父串中所有符合规则的子串提取出来。
#! /bin/awk -f
BEGIN {
#定义字符串变量
pages="p12-P34 P56-p78"
#通过循环依次匹配字符串中的数字
while(match(pages,/[0-9]+/)>0) {
#截取并输出匹配的子串
print substr(pages,RSTART,RLENGTH)
#删除匹配的子串
sub(/[0-9]+/,"",pages)
}
}
11.5.2 算术函数
awk提供了基本的执行算术运算的函数
int(x) 返回数值x的整数部分
sqrt(x) 返回数值x的平方根
exp(x) 返回e的x次方
log(x) 返回以e为底x的对数
sin(x) 返回x的正弦值
cos(x) 返回x的余弦值
rand() 返回介于0和1之间的随机数
srand([x]) 以x为种子返回一个随机数
11.6 数组
用户可以在awk编程环境中使用数组。这种特性使得用户在存储结构化的数据时变得非常方便。与其他的程序设计语言相比,awk中的数组有许多特殊的使用方法,本节将对这些使用方法进行详细介绍。
11.6.1 数组的定义和赋值
数组是用来存储一组相互关联的数据的结构体。在awk中,用户可以自定义数组,并且在定义数组时,毋需指定其类型和大小。
数组元素赋值的语法如下:
array[n]=value
其中,array表示数组名称,n表示数组元素的下标,等号为赋值运算符,value为要赋给数组元素的数值。
用户可以使用以下语法引用数组元素的值:
array[n]
其中,array表示数组名称,n为数组元素的下标。
#! /bin/awk -f
BEGIN {
#为数组元素赋值
arr[1]="Tim"
arr["a"]=12
arr[3]=3.1415
arr[4]=5
#输出数组元素的值
print arr[1],arr[2],arr["a"]*arr[3],arr[4]
}
11.6.2 遍历数组
所谓数组的遍历,是指将数组中的每个元素的值依次输出。
当然,用户可以通过循环结构来实现数组的遍历。
在使用正常的循环结构来遍历数组时,必须首先知道数组的长度,这样的话才能确定循环终止的条件。
在awk中,数组的长度可以使用length()函数获得,该函数以数组名作为参数,返回数组的长度。
#! /bin/awk -f
BEGIN {
#定义数组
stu[1]="200200110"
stu[2]="200200164"
stu[3]="200200167"
stu[4]="200200168"
stu[5]="200200172"
#计算数组的长度
len=length(stu)
#通过循环遍历数组
for(i=1;i<=len;i++)
{
print i,stu[i]
}
}
#! /bin/awk -f
BEGIN {
#定义数组
arr[1]="Tim"
arr[2]="John"
arr["a"]=12
arr[3]=3.1415
arr[4]=5
arr[99]=23
#遍历数组
for(n in arr)
{
print arr[n]
}
}
11.7 流程控制
作为一种程序设计语言,awk支持程序的流程控制,例如条件判断、循环以及其他的一些流程控制语句,例如continue、break以及exit等。掌握这些基本的流程控制语句,对于编写出结构良好的程序非常重要。本节将介绍awk流程控制语句的使用方法。
11.7.1 if语句
if语句的功能是根据用户指定的条件来决定执行程序的哪个分支,其语法如下:
if (expression){
statement1
statement2
}else {
statement3
statement4
}
#! /bin/awk -f
{
#90分以上为A
if ($2 >= 90) {
print $1,"A"
} else {
#80分以上为B
if($2 >= 80 && $2 < 90){
print $1,"B"
}
#其余为C
else
{
print $1,"C"
}
}
}
11.7.2 while语句
while语句是另外一种常用的循环结构,其语法如下:
while (expression)
{
statement1
statement2
...
}
当表达式expression的值为真时,执行循环体中的statement1以及statement2等语句。如果循环体中只包含一条语句,则可以省略大括号。
#! /bin/awk -f
BEGIN {
#定义循环变量
i=0
#while循环开始
while (++i <= 9)
{
#输出循环变量i的平方
print i^2
}
}
11.7.3 do…while语句
awk还支持另外一种while循环语句,其语法如下:
do {
statement1
statement2
...
} while (expression)
同样,当表达式expression的值为真时执行循环体中的语句。
#! /bin/awk -f
BEGIN {
#定义循环变量
i=1
do {
#输出循环变量的平方
print i^2
} while (++i<=9)
}
11.7.4 for语句
for循环语句通常用在循环次数已知的场合中,其语法如下:
for(expression1; expression2; expression3)
{
statement1
statement2
...
}
在上面的语法中,表达式expression1通常用来初始化循环变量,表达式expression2通常用来指定循环执行的条件,表达式expression3通常用来改变循环变量的值。当表达式expression2的值为真时,执行循环体中的语句。
#! /bin/awk -f
BEGIN {
#外层循环
for(i=1;i<=9;i++)
{
#内层循环
for(j=1;j<=i;j++)
{
#将每一行的数值连接成一个字符串
if(i*j<10)
{
row=row" "i*j
}
else
{
row=row" "i*j
}
}
#输出每一行数值
print row
row=""
}
}
11.7.5 break语句
用户可以通过使用break语句在适当的时机退出for以及while等循环结构,用来退出循环结构,而不必等到循环结构自己退出。
#! /bin/awk -f
BEGIN {
#循环读取数据
while( getline < "scores.txt" > 0 )
{
#当第1个字段的额值为Kity时退出
if($1=="Kity")
break
else
print $1,$2,$3,$4,$5 }
}
11.7.6 continue语句
continue语句的主要功能是跳过循环结构中该语句后面的尚未执行的语句。break语句与continue语句的功能有着明显的区别,前者是直接退出循环结构,而后者是跳过循环体中尚未执行的语句,重新执行下一次循环。
#! /bin/awk -f
BEGIN {
#通过循环读取数据
while( getline < "scores.txt" > 0 )
{
#当第1个字段含有字符串Nancy时跳过后面的语句
if($1 == "Kity")
continue
print $1,$2,$3,$4,$5
}
}
11.7.7 next语句
next语句的功能与continue语句非常相似,但是next语句并不是用在循环结构中,而是用在整个akw程序中。当awk执行程序时,如果遇到next语句,则该语句后面的所有的程序语句都被忽略,包括其他的模式以及对应的操作。awk会继续读取下一行数据,并且从第一个模式及其操作开始执行。
#! /bin/awk -f
#当读取的行为空行时跳过后面的语句
/^[\t]*$/ {
next
}
#输出各个字段
{
print $1,$2,$3,$4,$5
}
11.7.8 exit语句
exit语句的功能是终止awk程序的执行。
11.8 awk程序的格式化输出
对于程序来说,输出是一项非常重要的功能。而绝大部分的用户对于数据输出都有一定的格式要求。awk提供了基本的格式化输出功能,本节将介绍awk中与输出有关的函数。
11.8.1 基本print语句
print语句提供了基本的输出功能。我们在前面许多例子中,已经使用该语句来输出各种数据。print语句的基本语法如下:
print string1,string2,...
在上面的语法中,参数string1以及string2等是要输出的数据,各个参数之间使用逗号隔开。在输出的时候,print语句会自动使用空格将各个参数值隔开。
11.8.2 格式化输出printf语句
虽然大多数情况下awk的print语句可以完成任务,但有时我们还需要对格式做更多的控制。awk提供了printf函数来实现字符串的格式化。这个函数的功能和语法与C语言中的printf()函数基本相同,如下:
printf(format, [arguments])
其中圆括号是可选的,第1个参数format是一个用来描述输出格式的字符串,通常以引号括起来的字符串常量的形式提供。arguments为一个参数列表,表示用来显示的数据,可以是变量名等,多个参数之间用逗号隔开。参数列表的项是有顺序的,与前面的格式化字符串中的格式说明相对应。
格式化字符串的语法如下:
%format
#! /bin/awk -f
{
printf("%s\t%d\t%d\t%d\t%d\t%d\n",$1,$2,$3,$4,$5,($2 + $3 + $4 + $5))
}
11.8.3 使用sprintf()函数生成格式化字符串
sprintf函数的功能与printf函数的功能大致相同,但是该函数只是以字符串的形式返回格式化结果,并不输出到标准输出设备。用户可以将格式化的结果进行其他的处理或者使用print和printf函数输出到标准输出。
#! /bin/awk -f
BEGIN {
print "Scores list"
}
{
printf ("%s\t%d\t%d\t%d\t%d\t%d\n",$1,$2,$3,$4,$5,($2 + $3 + $4 + $5))
total+=$2 + $3 + $4 + $5
}
END {
average=total/NR
sum=sprintf("Total: %d students, average: %.2f",NR,average)
print sum
}
11.9 awk的程序与Shell的交互
awk提供了与Shell命令交互的能力,从而可以使得用户在awk程序中使用系统资源。awk主要通过2种机制来实现这种交互功能,分别为管道和Sytem函数。本节将对这2种交互机制进行详细介绍。
11.9.1 通过管道实现与Shell的交换
用户可以很容易地在awk程序中使用操作系统资源,包括在程序中调用Shell命令处理程序中的数据;或者在awk程序中获取Shell命令的执行结果。awk提供了管道来实现这种数据的双向交互。awk的管道与UNIX或者Linux中的管道非常相似,但是特性有些不同。
#! /bin/awk -f
BEGIN {
while("who" | getline) n++
printf("There %d online users.\n",n)
}
11.9.2 通过system函数实现与Shell的交互
awk提供另一个调用Shell命令的方法, 即使用awk函数,其语法如下:
system(command)
其中参数command表示要执行的Shell命令。与管道相比,system函数有许多据局限,例如不能在awk程序中直接获取Shell命令的执行结果,另外,也不能直接将awk程序中的数据传递给Shell命令来处理。要实现这种数据传递,必须借助其他的的一些手段。
#! /bin/awk -f
BEGIN {
system("ls > filelist")
while(getline < "filelist" > 0)
{
print $1
}
}