开发者

awk command in unix

why while loop is running only once in this following script?

#!/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 file contains:

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 contains:

AGA     Glasgow                       AQ

AGN     Newport                      TR

AGB     Br开发者_开发问答idgend                      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

I want output as:

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


Your while line should be

while ((getline < "portison.result") > 0)

otherwise the while comparison is ambiguous and will not be using the result of the getline

Also as @marco notes you need to close the file with close("portison.result") after the while loop


You have to close "portison.result" in order to force awk to open it again in the next read cycle; in addition, you need to avoid blank lines:

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


Depending on the size of your files and whether the order of the output is important, you may find this to be considerably faster than iterating over every line in one file for each line in the other:

#!/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]]
}

To run it:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜