awk 数组

简介:

                                                             字符串函数
gsub( Ere, Repl, [ In ] ) 除了正则表达式所有具体值被替代这点,它和 sub 函数完全一样地执行,。
sub( Ere, Repl, [ In ] ) 用 Repl 参数指定的字符串替换 In 参数指定的字符串中的由 Ere 参数指定的扩展正则表达式的第一个具体值。sub 函数返回替换的数量。出现在 Repl 参数指定的字符串中的 &(和符号)由 In 参数指定的与 Ere 参数的指定的扩展正则表达式匹配的字符串替换。如果未指定 In 参数,缺省值是整个记录($0 记录变量)。


index( String1, String2 ) 在由 String1 参数指定的字符串(其中有出现 String2 指定的参数)中,返回位置,从 1 开始编号。如果 String2 参数不在 String1 参数中出现,则返回 0(零)。


length [(String)] 返回 String 参数指定的字符串的长度(字符形式)。如果未给出 String 参数,则返回整个记录的长度($0 记录变量)。


blength [(String)] 返回 String 参数指定的字符串的长度(以字节为单位)。如果未给出 String 参数,则返回整个记录的长度($0 记录变量)。


substr( String, M, [ N ] ) 返回具有 N 参数指定的字符数量子串。子串从 String 参数指定的字符串取得,其字符以 M 参数指定的位置开始。M 参数指定为将 String 参数中的第一个字符作为编号 1。如果未指定 N 参数,则子串的长度将是 M 参数指定的位置到 String 参数的末尾 的长度。


match( String, Ere ) 在 String 参数指定的字符串(Ere 参数指定的扩展正则表达式出现在其中)中返回位置(字符形式),从 1 开始编号,或如果 Ere 参数不出现,则返回 0(零)。RSTART 特殊变量设置为返回值。RLENGTH 特殊变量设置为匹配的字符串的长度,或如果未找到任何匹配,则设置为 -1(负一)。


split( String, A, [Ere] ) 将 String 参数指定的参数分割为数组元素 A[1], A[2], . . ., A[n],并返回 n 变量的值。此分隔可以通过 Ere 参数指定的扩展正则表达式进行,或用当前字段分隔符(FS 特殊变量)来进行(如果没有给出 Ere 参数)。除非上下文指明特定的元素还应具有一个数字值,否则 A 数组中的元素用字符串值来创建。


tolower( String ) 返回 String 参数指定的字符串,字符串中每个大写字符将更改为小写。大写和小写的映射由当前语言环境的 LC_CTYPE 范畴定义。


toupper( String ) 返回 String 参数指定的字符串,字符串中每个小写字符将更改为大写。大写和小写的映射由当前语言环境的 LC_CTYPE 范畴定义。


sprintf(Format, Expr, Expr, . . . ) 根据 Format 参数指定的 printf 子例程格式字符串来格式化 Expr 参数指定的表达式并返回最后生成的字符串。


3.时间函数
mktime( YYYY MM DD HH MM SS[ DST]) 生成时间格式


strftime([format [, timestamp]]) 格式化时间输出,将时间戳转为时间字符串,具体格式如下:


%a 星期几的缩写(Sun)
%A 星期几的完整写法(Sunday)
%b 月名的缩写(Oct)
%B 月名的完整写法(October)
%c 本地日期和时间
%d 十进制日期
%D 日期 08/20/99
%e 日期,如果只有一位会补上一个空格
%H 用十进制表示24小时格式的小时
%I 用十进制表示12小时格式的小时
%j 从1月1日起一年中的第几天
%m 十进制表示的月份
%M 十进制表示的分钟
%p 12小时表示法(AM/PM)
%S 十进制表示的秒
%U 十进制表示的一年中的第几个星期(星期天作为一个星期的开始)
%w 十进制表示的星期几(星期天是0)
%W 十进制表示的一年中的第几个星期(星期一作为一个星期的开始)
%x 重新设置本地日期(08/20/99)
%X 重新设置本地时间(12:00:00)
%y 两位数字表示的年(99)
%Y 当前月份
%Z 时区(PDT)
%% 百分号(%)


systime() 得到时间戳,返回从1970年1月1日开始到当前时间(不计闰年)的整秒数





一、定义方法

 

1:可以用数值作数组索引(下标)

Tarray[1]=“cheng mo”
Tarray[2]=“800927”

2:可以用字符串作数组索引(下标)

Tarray[“first”]=“cheng ”
Tarray[“last”]=”mo”
Tarray[“birth”]=”800927”

使用中 print Tarray[1] 将得到”cheng mo” 而 print Tarray[2] 和 print[“birth”] 都将得到 ”800927” 。

 

二、数组相关函数

[chengmo@localhost ~]$ awk --version
GNU Awk 3.1.5

使用版本是:3.1以上,不同版本下面函数不一定相同

  • 得到数组长度(length方法使用

split( String, A, [Ere] ) 将 String 参数指定的参数分割为数组元素 A[1], A[2], . . ., A[n],并返回 n 变量的值。


length [(String)] 返回 String 参数指定的字符串的长度(字符形式)。如果未给出 String 参数,则返回整个记录的长度($0 记录变量)。

[chengmo@localhost ~]$ awk 'BEGIN{info="it is a test";lens=split(info,tA," ");print length(tA),lens;}'
4 4

length返回字符串以及数组长度,split进行分割字符串为数组,也会返回分割得到数组长度。

 awk 'BEGIN{info="it is a test";lens=split(info,tA," ");print tA[1],lens;}'

it 4

awk 'BEGIN{info="it is a test";lens=split(info,tA," ");print tA[2],lens;}'

is 4

awk 'BEGIN{info="it is a test";lens=split(info,tA," ");print tA[3],lens;}'

a 4

awk 'BEGIN{info="it is a test";lens=split(info,tA," ");print tA[4],lens;}'

test 4

(asort使用):

[chengmo@localhost ~]$ awk 'BEGIN{info="it is a test";split(info,tA," ");print asort(tA);}'
4

asort对数组进行排序,返回数组长度。

 

  • 输出数组内容(无序,有序输出):

[chengmo@localhost ~]$ awk 'BEGIN{info="it is a test";split(info,tA," ");for(k in tA){print k,tA[k];}}'
4 test
1 it
2 is
3 a

 

for…in 输出,因为数组是关联数组,默认是无序的。所以通过for…in 得到是无序的数组。如果需要得到有序数组,需要通过下标获得。

 

[chengmo@localhost ~]$ awk 'BEGIN{info="it is a test";tlen=split(info,tA," ");for(k=1;k<=tlen;k++){print k,tA[k];}}' 
1 it
2 is
3 a
4 test

注意:数组下标是从1开始,与c数组不一样。

 

 

  • 判断键值存在以及删除键值:

一个错误的判断方法

[chengmo@localhost ~]$ awk 'BEGIN{tB["a"]="a1";tB["b"]="b1";if(tB["c"]!="1"){print "no found";};for(k in tB){print k,tB[k];}}' 
no found
a a1
b b1
c

 

以上出现奇怪问题,tB[“c”]没有定义,但是循环时候,发现已经存在该键值,它的值为空,这里需要注意,awk数组是关联数组,只要通过数组引用它的key,就会自动创建改序列.

 

正确判断方法:

[chengmo@localhost ~]$ awk 'BEGIN{tB["a"]="a1";tB["b"]="b1";if( "c" in tB){print "ok";};for(k in tB){print k,tB[k];}}'  
a a1
b b1

if(key in array) 通过这种方法判断数组中是否包含”key”键值。

 

删除键值:

[chengmo@localhost ~]$ awk 'BEGIN{tB["a"]="a1";tB["b"]="b1";delete tB["a"];for(k in tB){print k,tB[k];}}'                     
b b1

 

delete array[key]可以删除,对应数组key的,序列值。

 

三、二维数组使用(多维数组使用)

awk的多维数组在本质上是一维数组,更确切一点,awk在存储上并不支持多维数组。awk提供了逻辑上模拟二维数组的访问方式。例 如,array[2,4] = 1这样的访问是允许的。awk使用一个特殊的字符串SUBSEP (\034)作为分割字段,在上面的例子中,关联数组array存储的键值实际上是2\0344。

 

类似一维数组的成员测试,多维数组可以使用 if ( (i,j) in array)这样的语法,但是下标必须放置在圆括号中。
类似一维数组的循环访问,多维数组使用 for ( item in array )这样的语法遍历数组。与一维数组不同的是,多维数组必须使用split()函数来访问单独的下标分量。split ( item, subscr, SUBSEP)

 

[chengmo@localhost ~]$ awk 'BEGIN{

for(i=1;i<=9;i++)
{
  for(j=1;j<=9;j++)  
  {
tarr[i,j]=i*j;
print i,"*",j,"=",tarr[i,j];
  }
}
}'
1 * 1 = 1
1 * 2 = 2
1 * 3 = 3
1 * 4 = 4
1 * 5 = 5
1 * 6 = 6

……

可以通过array[k,k2]引用获得数组内容.

 

方法二:

[chengmo@localhost ~]$ awk 'BEGIN{
for(i=1;i<=9;i++)
{
  for(j=1;j<=9;j++)  
  {
tarr[i,j]=i*j;
  }
}
for(m in tarr)              
{

split(m,tarr2,SUBSEP);
print tarr2[1],"*",tarr2[2],"=",tarr[m];
}
}'

 


一、定义

在 awk 中,数组是关联数组,它的特点是:

1、 数组的下标可以是整数,也可以是负数甚至是字符串

2、 数组的下标可以不连续。

Awk 的变量 IGNORECASE 的值不影响数组下标。

当 awk 创建一个数组的时候,如果没有指定下标,默认已连续整数作为下标,起始值是 1.

Awk 的数组是什么高效的,访问一个元素的时间跟元素的数量无关。

注: awk 的下标其实都是字符串,如我们输入的是数字 1 , awk 会自动的转换为字符串“ 1 ”

二、引用元素

引用 awk 元素的基本方法是:

ARRAY[INDEX]

注: 在此引用方式中除非 [ ] 中写的是变量,否则需要添加双引号,即字符串必需添加双引号的规则在数组的下标中也必需遵守,但如果下标是全数字,则可以不加引号,例:

Bb=“123”

arr[bb] awk 将 bb 认作变量,获取的是 arr[“123”] 的值

arr[234] awk 将 234 认作字符串,虽然 234 没加引号。因为变量的定义不能用全数字,所以 234 肯定是字符串,而不是变量。

arr[“ bb” ] awk 将 bb 认作字符串,获取的是 arr[“bb”] 的值

有时候,数组的 value 会为空。 value 为空的元素包含两种情况 1 、本身 value 为空 2 、通过 delete 删除后的元素。这两种情况都可以被正常引用。但不幸的是,如果引用了一个不存在的元素,会导致 awk 创建这个元素, value 为空,这样,会导致 awk 的内存浪费。

如果要查询具有某个 index 值的元素是否存在可以用如下的表达式:

INDEX in ARRAY

这个表达式仅仅测试具有 INDEX 的元素在 ARRAY 中是否存在。如果不存在,该表达式不会导致产生以 INDEX 为下标的 value 为空的元素。

如果元素存在,该表达式返回值 1 ( true 

反之,返回 0 ( false 

例:测试在数组 frequencies 中是否存在下标为 2 的元素

if (2 in frequencies)

print “Sub 2 is present.”

注: 不能测试 frequencies 中是否存在 value 为 的元素,除非 scan 数组中的所有元素。

三、给元素赋值

给 awk 的数组赋值,只能采用如下形式:

ARRAY[SUB] = VALUE

ARRAY :数组名字

SUB :下标

VALUE :值

注: awk 可以生成下标为空的元素,但是引用方式必需是 arr[ “” ], 而不是 arr[]

length(a) 求得数组中元素的个数。

四、遍历数组

在使用数组的程序里,经常会使用一个循环让数组里的每一个元素都执行一次某一个操作。在其他程序里,数组的下标是连续的正整数,因此所有的下标很容易通过从低到高实现遍历。但这个方法在 awk 里不能使用,因为 awk 的下标可以是数字也可以是字符串。因此, awk 使用一种特别的语句来遍历数组里的元素:

for (VAR in ARRAY)

BODY

以上的循环将实现让数组 ARRAY 里的每一个元素都执行一次 BODY 

以下程序的第一部分,将输入文本的每一个单词都作为下标存放入数组,如单词有重复,仅仅保留一个,因数组的下标是不能重复的。

五、删除元素

删除单个元素

delete ARRAY[INDEX]

删除整个数组方法 1

for (VAR in ARRAY)

delete ARRAY[VAR]

删除整个数组方法 (该方法 gawk 专用,可移植性差,但效率是方法 的 倍左右)

delete ARRAY

Awk 的数组和变量用的是同一个地址空间,数组的名字和变量不能重名。即使数组删除了也不能将名字用于变量命名,以下命令会报错:

a[1] = 3; delete a; a = 3

六、数组赋值

单个赋值: Tarray[1]="cheng mo"  Tarray[2]="800927"

多个赋值:awk 'BEGIN{info="it is a test"; lens=split(info,tA," "); print length(tA), lens, tA[1];}'










本文转自 chengxuyonghu 51CTO博客,原文链接:http://blog.51cto.com/6226001001/1628028,如需转载请自行联系原作者
目录
相关文章
|
6月前
|
Perl
在 `awk` 中,for 循环
在 `awk` 中,for 循环
613 5
|
6月前
|
C语言 索引 Perl
在awk中遍历数组
在awk中遍历数组
176 8
|
6月前
|
Perl
awk循环处理
awk循环处理
186 8
|
人工智能 BI Perl
|
索引 Perl 存储
|
Perl Linux 数据格式
|
索引 Perl 存储