免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3106 | 回复: 16
打印 上一主题 下一主题

[文本处理] awk 数组的小疑问求解 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-10-11 13:04 |只看该作者 |倒序浏览
本帖最后由 aingwen 于 2014-10-11 13:39 编辑

awk '{a[$1,$2]=$3}' 和 awk '{a[$1","$2]=$3}' 两者的区别该怎么理解?

补充,问题是从http://bbs.chinaunix.net/thread-4156849-1-1.html 里面遇到,测试的时候,中间的双引号漏写了,执行完后的结果就不一样了

论坛徽章:
32
处女座
日期:2013-11-20 23:41:20双子座
日期:2014-06-11 17:20:43戌狗
日期:2014-06-16 11:05:00处女座
日期:2014-07-22 17:30:47狮子座
日期:2014-07-28 15:38:17金牛座
日期:2014-08-05 16:34:01亥猪
日期:2014-08-18 13:34:25白羊座
日期:2014-09-02 15:03:55金牛座
日期:2014-11-10 10:23:58处女座
日期:2014-12-02 09:17:52程序设计版块每日发帖之星
日期:2015-06-16 22:20:002015亚冠之塔什干火车头
日期:2015-06-20 23:28:22
2 [报告]
发表于 2014-10-11 13:42 |只看该作者
只能说用for循环遍历数组时,后者比前者方便。

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
3 [报告]
发表于 2014-10-11 13:57 |只看该作者

论坛徽章:
5
白羊座
日期:2014-10-28 11:23:27水瓶座
日期:2015-01-20 10:19:022015亚冠之柏斯波利斯
日期:2015-07-11 18:17:2015-16赛季CBA联赛之同曦
日期:2015-12-23 12:38:582016猴年福章徽章
日期:2016-02-18 15:30:34
4 [报告]
发表于 2014-10-11 14:20 |只看该作者
本帖最后由 klainogn 于 2014-10-11 14:39 编辑

用 , 和SUBSEP是等效的,实际字符的ASCII码是 1C,
而","仅仅是一个字符逗号,其ASCII码是 2C,
正如二楼所说,前者方便,因为普通文本中不太可能有 0x1C 这个字符,而0x2C却是很常见,对组合式的数组索引进行分割时前者不会发生误分割的情况

论坛徽章:
2
摩羯座
日期:2014-11-03 15:28:56卯兔
日期:2015-01-04 17:20:51
5 [报告]
发表于 2014-10-11 14:46 |只看该作者
回复 1# aingwen


    没引号数字下标是用SUBSEP间隔,有引号是用逗号间隔,间隔方式不一样

论坛徽章:
22
处女座
日期:2014-10-11 13:33:292015亚冠之塔什干火车头
日期:2015-07-20 19:59:042015亚冠之塔什干火车头
日期:2015-07-26 10:59:31程序设计版块每日发帖之星
日期:2015-08-05 06:20:00每日论坛发贴之星
日期:2015-08-05 06:20:00程序设计版块每日发帖之星
日期:2015-08-07 06:20:00每日论坛发贴之星
日期:2015-08-07 06:20:002015亚冠之阿尔纳斯尔
日期:2015-10-01 15:23:28白银圣斗士
日期:2015-12-07 17:17:06操作系统版块每日发帖之星
日期:2015-12-27 06:20:002015亚冠之广州富力
日期:2015-07-08 15:48:31程序设计版块每日发帖之星
日期:2015-06-11 22:20:00
6 [报告]
发表于 2014-10-11 18:33 |只看该作者
回复 5# bulletmarquis
正解

   

论坛徽章:
3
丑牛
日期:2014-09-13 18:19:22摩羯座
日期:2014-10-10 17:43:02水瓶座
日期:2014-10-16 01:00:22
7 [报告]
发表于 2014-10-11 20:13 |只看该作者
其实就一句话怎么存就怎么取....这没啥纠结的哦

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
8 [报告]
发表于 2014-10-11 21:35 |只看该作者
本帖最后由 jason680 于 2014-10-11 21:37 编辑

回复 1# aingwen

a[key] = value;

finally, key will be a string in awk

$ echo a b c | awk '{a[$1,$2]=$3;for(n in a)print n"="a[n]}' | hexdump -C
00000000  61 1c 62 3d 63 0a                                 |a.b=c.|
Note: ASCII 0x1C is non-printing control charact

$ echo a b c | awk '{a[$1","$2]=$3;for(n in a)print n"="a[n]}' | hexdump -C
00000000  61 2c 62 3d 63 0a                                 |a,b=c.|

===================================
$ echo a b c | awk 'function p(s){print s" ---";for(n in a)print n"="a[n]}BEGIN{a[01]="01N";a[02]="02N";a["01"]="01S";a["02"]="02S";p("at BEGIN")}{for(n=1;n<=NF;n++)a[n]=$n;p("at Line"NR)}END{a["1"]="1S";a["2"]="2S";p("at END")}'
at BEGIN ---
01=01S
02=02S
1=01N
2=02N
at Line1 ---
01=01S
02=02S
1=a
2=b
3=c

at END ---
01=01S
02=02S
1=1S
2=2S
3=c
=====================================

http://www.gnu.org/software/gawk/manual/gawk.html#Multidimensional
8.5 Multidimensional Arrays
• Multiscanning:                  Scanning multidimensional arrays.

A multidimensional array is an array in which an element is identified by a sequence of indices instead of a single index. For example, a two-dimensional array requires two indices. The usual way (in most languages, including awk) to refer to an element of a two-dimensional array named grid is with grid[x,y].

Multidimensional arrays are supported in awk through concatenation of indices into one string. awk converts the indices into strings (see Conversion) and concatenates them together, with a separator between them. This creates a single string that describes the values of the separate indices. The combined string is used as a single index into an ordinary, one-dimensional array. The separator used is the value of the built-in variable SUBSEP.

For example, suppose we evaluate the expression ‘foo[5,12] = "value"’ when the value of SUBSEP is "@". The numbers 5 and 12 are converted to strings and concatenated with an ‘@’ between them, yielding "5@12"; thus, the array element foo["5@12"] is set to "value".

Once the element’s value is stored, awk has no record of whether it was stored with a single index or a sequence of indices. The two expressions ‘foo[5,12]’ and ‘foo[5 SUBSEP 12]’ are always equivalent.

The default value of SUBSEP is the string "\034", which contains a nonprinting character that is unlikely to appear in an awk program or in most input data. The usefulness of choosing an unlikely character comes from the fact that index values that contain a string matching SUBSEP can lead to combined strings that are ambiguous. Suppose that SUBSEP is "@"; then ‘foo["a@b", "c"]’ and ‘foo["a", "b@c"]’ are indistinguishable because both are actually stored as ‘foo["a@b@c"]’.

论坛徽章:
0
9 [报告]
发表于 2014-10-13 16:06 |只看该作者
回复 8# jason680
先感谢大神的耐心讲解
$ echo a b c | awk '{a[$1,$2]=$3;for(n in a)print n"="a[n]}' | hexdump -C
00000000  61 1c 62 3d 63 0a                                 |a.b=c.|
Note: ASCII 0x1C is non-printing control charact

$ echo a b c | awk '{a[$1","$2]=$3;for(n in a)print n"="a[n]}' | hexdump -C
00000000  61 2c 62 3d 63 0a                                 |a,b=c.|
1 这一部份我能看明白,正如前面几楼的朋友解释的间隔方式不同,但是:
awk 'BEGIN{for(i=1;i<=9;i++){for(j=1;j<=9;j++){ta[i,j]=i*j;print i,"*",j,"=",ta[i,j];}}}'
awk 'BEGIN{for(i=1;i<=9;i++){for(j=1;j<=9;j++){ta[i","j]=i*j;print i,"*",j,"=",ta[i","j];}}}'
. 这两句执行结果又相同哦,这里我的疑问是什么情况下一定要加引号,什么情况下可以不用加引号?

2. 下面这个例子
echo a b c | awk 'function p(s){print s" ---";for(n in a)print n"="a[n]}BEGIN{a[01]="01N";a[02]="02N";a["01"]="01S";a["02"]="02S";p("at BEGIN")}{for(n=1;n<=NF;n++)a[n]=$n;p("at Line"NR)}END{a["1"]="1S";a["2"]="2S";p("at END")}'
我看到 a[01] 与 a["01"] 这里面  01 与 "01" 是有区别,
在at BEGIN--- 这里1=01N 这个1是数值01  
在at END---   这里1="1S" 这个1 是字符串1
是这样理解吗?
   

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
10 [报告]
发表于 2014-10-13 17:25 |只看该作者
本帖最后由 jason680 于 2014-10-13 17:56 编辑

回复 9# aingwen

a[key] = value;

finally, the key will be a string in awk
   

$ echo a b c | awk 'function p(s){print s" ---";for(n in a)print "a[\""n"\"]="a[n]}BEGIN{a[01]="01N";a[02]="02N";a["01"]="01S";a["02"]="02S";p("at BEGIN")}{for(n=1;n<=NF;n++)a[n]=$n;p("at Line"NR)}END{a["1"]="1S";a["2"]="2S";p("at END")}'
at BEGIN ---
a["01"]=01S
a["02"]=02S
a["1"]=01N
a["2"]=02N
at Line1 ---
a["01"]=01S
a["02"]=02S
a["1"]=a
a["2"]=b
a["3"]=c
at END ---
a["01"]=01S
a["02"]=02S
a["1"]=1S
a["2"]=2S
a["3"]=c

Note:
a[01] = xxx;
  01 is number(1) and transfer to string will be "1", finally, a["1"] = xxx;
a[2*5] = xxx;
  2*5 is number(10) and transfer to string will be "10", finally, a["10"] = xxx;
a["01"] = yyy;
   "01" is string already, finally, a["01"]=yyy;

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP