Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
AWK:使用内联if-then-else的健壮方法_Awk - Fatal编程技术网

AWK:使用内联if-then-else的健壮方法

AWK:使用内联if-then-else的健壮方法,awk,Awk,我经常使用内联if-then-else语句(…?…:…)将输入文件的字段与分隔符(逗号、冒号、分号…)连接在一起 典型的用例是使用输入文件的字段构建字符串,并将该字符串存储在数组中,如下所示: $ cat file a 1 b 2 a 3 c 1 b 26 c 4 c 2 为了转置这样的文件,我使用以下awk脚本: awk '{a[$1]=a[$1](a[$1]?",":"")$2}END{for(i in a) printf "%s:%s\n",i,a[i]}' file 这种使用inli

我经常使用内联if-then-else语句
(…?…:…)
将输入文件的字段与分隔符(逗号、冒号、分号…)连接在一起

典型的用例是使用输入文件的字段构建字符串,并将该字符串存储在数组中,如下所示:

$ cat file
a 1
b 2
a 3
c 1
b 26
c 4
c 2
为了转置这样的文件,我使用以下awk脚本:

awk '{a[$1]=a[$1](a[$1]?",":"")$2}END{for(i in a) printf "%s:%s\n",i,a[i]}' file
这种使用inline if-then-else的方法不够健壮,我应该使用这种方法:

awk '{a[$1]=($1 in a?a[$1]",":"")$2}END{for(i in a) printf "%s:%s\n",i,a[i]}' file
显然,对于这个简单的输入文件,两个脚本的结果是相同的

那么为什么第二个脚本会更“健壮”


实际上,我正在寻找一个输入示例,它会使第一个脚本失败,而不会使另一个脚本失败。

首先,我猜您在第一个awk单行程序中又添加了一个
a[$1]=
。应该是:

awk '{a[$1]=a[$1](a[$1]?",":"")$2}....
我想你的问题是为什么在一个中检查
$1要比检查
一个[$1]
好。这两个一行程序都适用于您的输入。因为字符串串联使
a[$1]
变成了字符串。对于字符串,如果它不是空的,awk将把它计算为
true
。也适用于字符串
“0”

但是,如果您必须以数字的形式处理输入以适应所需的输出,那么这两种布尔检查可能会有所不同。如果一个数字是
0
,awk将计算为
false

看看这个例子:

kent$  awk 'BEGIN{if(0)print "number"; if("0")print "string"}'
string
你看,只有后面的那一张被打印出来了

因此,a
中的
$1更好,因为无论
a[$1]
存储一个数字或字符串,它都将始终工作

但是,如果您在代码中设置了
a[$1]
,并且100%确定
布尔值a[$1]
将给出您期望的值,则可以使用
if(a[$1])
检查。例如,您在代码中进行了字符串连接
“$2
。或者您可以设置类似于
a[$1]=1


一般<代码> < /COD>中的1美元更好。

< P>除了@ Kent所提到的之外,考虑到一般字段可以是空字符串。提示您当前问题的有CSV输入,因此,现在让我们再次使用该输入,以获得比空间分隔更好的可见性:

$ cat file
a,1
b,
a,3
c,
b,26
c,4
c,2

$ awk -F',' '{a[$1]=a[$1](a[$1]?",":"")$2}END{for(i in a) printf "%s:%s\n",i,a[i]}' file
a:1,3
b:26
c:4,2

$ awk -F',' '{a[$1]=($1 in a?a[$1]",":"")$2}END{for(i in a) printf "%s:%s\n",i,a[i]}' file
a:1,3
b:,26
c:,4,2

另一件事是,
if(a[$1])
实际上会向索引为
$1
a
数组添加一个条目,而
中的
$1则不会。在某些情况下,这可能是内存问题,甚至可能影响程序的逻辑。FYI
inline if-then-else语句
=
三元表达式
。看:这里的答案都没有回答你的问题吗?如果您有后续问题,请让我们知道,否则请查看下一步要做什么。