关于awk数组的问题、
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于awk数组的问题、相关的知识,希望对你有一定的参考价值。
一直不是很明白awk的数组、想问高人一下、a[$0]++、a[$0++]、a[$1]++、$[$1++]、还有a[NF++]、a[NF]++和a[NR++]、a[NR]++各用在什么地方、也就是在需要实现什么结果的时候用、最好举例说明、悬赏50份、谢谢啦
参考技术A awk是按行处理文本数据的。awk中的术语将一行称为一个记录;一个记录还可以根据分隔符分割为多个字段。
$0 表示整行内容(一个记录)
a[$0]++用于分别统计不相同的记录个数。即,相同$0内容,个数累加。
例子:
文件1.txt内容为:
111 abc
222 abc
333 efg
想得到如下结果(即统计第二个字段出现的次数):
abc 2
efg 1
这个用awk就可以这样写:
awk ' w[$2]+=1 END for (a in w) print a, w[a]' 1.txt
解析:
$2表示第二个字段,用 w[abc] 表示abc出现的次数,w[efg]表示efg出现的次数。当$2=abc的时候,累加w[abc];当$2=efg的时候,累加w[efg]。这样,w就是一个包含所有$2字段的集合,最后通过for循环,把各自出现的次数都打印出来。
其实,真正弄懂了这一个,举一反三,其他都会了。
在 awk 循环中访问 bash 数组
【中文标题】在 awk 循环中访问 bash 数组【英文标题】:Access a bash array in awk loop 【发布时间】:2015-09-01 02:50:31 【问题描述】:我有一个类似的 bash 数组
myarray = (1 2 3 4 5 ... n)
另外我正在读取一个只有一行输入的文件,例如:
1 2 3 4 5 ... n
我正在将它逐行读取到一个数组中并打印:
awk 'BEGINFS=OFS="\t"
NR>=1for (i=1;i<=NF;i++) a[i]+=$i
ENDfor (i=1;i<NF;i++) print OFS a[i]' myfile.txt
myarray
的大小与a
相同。现在myarray
以索引0
开始,a
以索引1
开始。我的主要问题是如何将 bash 数组传递给我的 awk 表达式,以便我可以在打印循环中使用它和相应的元素。所以我尝试的是这样的:
awk -v array="$myarray[*]"
'BEGINFS=OFS="\t"
NR>=1for (i=1;i<=NF;i++) a[i]+=$i
ENDfor (i=1;i<NF;i++) print OFS a[i] OFS array[i-1]' myfile.txt
但这不起作用。我没有得到myarray
的任何输出。在这个例子中我想要的输出是:
1 1
2 2
3 3
4 4
5 5
...
n n
【问题讨论】:
【参考方案1】:据我了解,您只需要以正确的方式使用 bash 数组输入 awk
。也就是说,通过使用split()
:
awk -v bash_array="$myarray[*]"
'BEGINsplit(bash_array,array); FS=OFS="\t"
NR>=1for (i=1;i<=NF;i++) a[i]+=$i
ENDfor (i=1;i<NF;i++) print a[i], array[i]' file
由于数组array[]
现在在awk
中,因此您不必关心索引,因此您可以正常调用它们,而不必担心bash 中从0
开始的那些。
还请注意,print a,b
与 print a OFS b
相同(并且更简洁),因为您已经在 BEGIN
块中定义了 OFS
。
【讨论】:
谢谢。这就是问题所在!只是在一边:是否可以做类似OFS="\t\t"
的事情。因为有时我需要其中两个才能正确对齐数字。
@uitty400 当然可以,您可以使用echo "1 2 3" | awk 'BEGIN OFS="\t\t" print $1, $2'
进行测试。
@uitty400 你可能需要说BEGINFS="\t"; OFS="\t\t"
。甚至FS="\t"; OFS=FS FS
!! (我对此感到惊讶)
就是这样。感谢您的帮助!以上是关于关于awk数组的问题、的主要内容,如果未能解决你的问题,请参考以下文章