unix中的awk命令

时间:2011-01-11 10:40:57

标签: awk

为什么while循环在以下脚本中只运行一次?

#!/bin/ksh
awk '
{site=$1; print $2;
    while (getline <"portison.result")
    {
      var=substr($2, 0, 3)
      if (site == var)
          print $0
    }
}
' sites.cfg

portison.result文件包含:

0       AGAMS3  EDGE    NTS     2347629,,,RHe

10      AGNSD9  EDGE    NTS     2340447,,,TRf

100     AGBSN0  EDGE    NTS     2323735,,,BRc

2       AGUMS3  EDGE    NTS     2347629,,,RHe

20      AGWSD9  EDGE    NTS     2340447,,,TRf

200     AGLSN0  EDGE    NTS     2323735,,,BRc

3       AGDMS3  EDGE    NTS     2347629,,,RHe

30      AGSSD9  EDGE    NTS     2340447,,,TRf

300     AGESN0  EDGE    NTS     2323735,,,BRc

4       AGNSD9  EDGE    NTS     2340447,,,TRf

40      AGAMS3  EDGE    NTS     2347629,,,RHe

400     AGCSN0  EDGE    NTS     2323735,,,BRc

5       AGISN0  EDGE    NTS     2323735,,,BRc

500     AGISN0  EDGE    NTS     2323735,,,BRc

sites.cfg包含:

AGA     Glasgow                       AQ

AGN     Newport                      TR

AGB     Bridgend                      BR

AGU     Sunderland                   RH

AGW     Swansea                       SW

AGL     Marine Wharf               MW

AGD     Dudley                          DU

AGS     Brighton                       SU

AGE     Southend                      ES

AGC     Solent                          CH

AGI     Isle of Man                  IM and PB

我希望输出为:

Glasgow
0 AGAMS3 EDGE NTS 2347629,,,RHe
40 AGAMS3 EDGE NTS 2347629,,,RHe

Newport
10 AGNSD9 EDGE NTS 2340447,,,TRf
4 AGNSD9 EDGE NTS 2340447,,,TRf

Bridgend
100 AGBSN0 EDGE NTS 2323735,,,BRc

Sunderland
2 AGUMS3 EDGE NTS 2347629,,,RHe

Swansea
20 AGWSD9 EDGE NTS 2340447,,,TRf

Marine
200 AGLSN0 EDGE NTS 2323735,,,BRc

Dudley
3 AGDMS3 EDGE NTS 2347629,,,RHe

Brighton
30 AGSSD9 EDGE NTS 2340447,,,TRf

Southend
300 AGESN0 EDGE NTS 2323735,,,BRc

Solent
400 AGCSN0 EDGE NTS 2323735,,,BRc

Isle
5 AGISN0 EDGE NTS 2323735,,,BRc
500 AGISN0 EDGE NTS 2323735,,,BRc

3 个答案:

答案 0 :(得分:2)

你的时间线应该是

  

while((getline&lt;“portison.result”)&gt; 0)

否则while比较不明确,不会使用getline的结果

同样正如@marco所说,你需要在while循环之后用close("portison.result")关闭文件

答案 1 :(得分:2)

你必须关闭“portison.result”才能强制awk在下一个阅读周期中再次打开它;另外,你需要避免空行:

awk '
    !/^$/{
        site=$1; 
        printf $2;

        while (getline <"portison.result") {
            var=substr($2, 0, 3)
            if (site == var)
                printf " " $0
        }
        print "";
        close("portison.result");
    }' sites.cfg

答案 2 :(得分:0)

根据文件的大小以及输出的顺序是否重要,您可能会发现这比在另一个文件中为每一行迭代遍历每一行要快得多:

#!/usr/bin/awk -f
NR==FNR {
    sites[$1] = $2
    indices[c++] = $1
    next
}
{
    idx = substr($2, 0, 3)
    lines[idx] = lines[idx] "\n" $0
}
END {
    for (i=0;i<=c;i++) print sites[indices[i]] lines[indices[i]]
}

运行它:

 $ ./script.awk sites.cfg portison.result