红联Linux门户
Linux帮助

求助:这一小段awk代码,问题出在哪里?

发布时间:2011-04-17 17:17:44来源:红联作者:huazhorg
我编写了一awk段代码test.awk,内容如下:
#!/bin/awk -f
BEGIN{}
{
for(i=1;i<=NF;i++){
if($i=="celldm(1)="){a=$(NF=i+1);print "a="a}
else if($i=="celldm(2)="){b=$(NF=i+1);print "b="b}
else if($i=="celldm(3)="){c=$(NF=i+1);print "c="c}
else if($i=="celldm(4)="){d=$(NF=i+1);print "d="d}
}
}
END{}
处理的目标文本tmpfile, 内容如下:
system
ibrav= 12 celldm(1)= 10.38828296 celldm(2)= 0.69047339
celldm(3)= 4.44037202
celldm(4)= -0.3452367
nat= 22, ntyp=4
运行 ./test.awk tmpfile后,结果如下:
a=10.38828296
c=4.44037202
d=-0.3452367

请问,为何没有打印b?怎么改,才能打印b? 谢谢各位!
文章评论

共有 4 条评论

  1. yanyongkg 于 2011-04-25 22:33:43发表:

    [i=s] 本帖最后由 yanyongkg 于 2011-4-25 22:42 编辑 [/i]

    原因如下
    罗嗦一下把整个执行过程写一写:
    1。读取第一行,for循环完成,不符合条件,没有执行if后面{}里的内容
    2。读取第二行:
    ibrav= 12 celldm(1)= 10.38828296 celldm(2)= 0.69047339
    对应的$1为ibrav=,$2为12,$3为celldm(1)=,$4为10.38828296,$5为celldm(2)=,$6为0.69047339
    i初始值为1,NF初值为6的,for循环到i为3时,"$3"=="celldm(1)="成立,执行后面的a=$(NF=i+1);print "a="a ,此句意思a变量为$4而不是把把4赋值给a,打印出a=10.38828296
    问题就出在NF=i+1,这样会把awk的内建变量NF赋值为4了
    i为3循环完,然后for循环到i为4就是最后一次循环了,因为i<=NF,所以条件都不符合,跳出。
    awk第二行处理完毕。
    3。读取第三行:
    celldm(3)= 4.44037202
    对应$1为celldm(3)=,$2为4.44037202
    读取第三行时awk有个动作会把NF又初始为2,这里NF不是刚才的读完第二行的值4,这两只有两个字段看不出,你可以把第二行改为a b c d e f g celldm(3)= 4.44037202,这样的NF会是9,这里可以证明awk读取行是会初始化NF(如果NF为4的话celldm(3)是匹配不到的)。
    4。读取第4行,第5行,你懂的。

    正解:把a=$(NF=i+1)改成a=$(nu=i+1)或a=$(i+1)
    此处nu变量是随便取的,只要不用awk的内建变量NF就行,当然这个nu变量有点多余,用a=$(i+1)就可以了

  2. yanyongkg 于 2011-04-22 09:48:38发表:

    没人反对或认同2楼及3楼的解答?

  3. yanyongkg 于 2011-04-19 18:03:40发表:

    [i=s] 本帖最后由 yanyongkg 于 2011-4-25 21:56 编辑 [/i]

    此处为误解,现已自行删除。

    正解在4楼

  4. yanyongkg 于 2011-04-18 01:16:57发表:

    [i=s] 本帖最后由 yanyongkg 于 2011-4-25 21:56 编辑 [/i]

    试了一下,确实如你所说的b打印不出。
    原因可能是这样的,个人意见,仅供参考。

    说说awk处理过程
    步骤1:读取文件的第一行
    步骤2:将读取的这一行按照分隔符分割成数个字段,默认分隔符为空白键(我理解这的空白符也包括TAB,不知正解与否)。将第一个字段放入到变量$1中,第二个放到$2中,$0表示整行
    步骤3:根据条件判断来决定是否执行后面的动作
    步骤4:读取文件第二行及后面所有行,重复步骤1至步骤3

    test.awk来处理tmpfile文件的过程大概是这样的(个人理解不一定说法妥当,仅供参考):

    自处为误解,现已自行删除。