多个if条件AWK

时间:2015-02-22 10:56:16

标签: bash if-statement awk

我有一个非常大的文件,包含德国邮政编码/邮政编码。对于每个代码,我想找到正确的联邦州。我做的是以下内容。

  1. 我将zipcodes打印在一个新文件中。
  2. 我对它们进行了整理,并将双重案件踢了出来。 现在我有了一个包含2267种不同邮政编码的新文件。
  3. 我创建了一个awk命令,它应该为每个代码找到一个名称。
  4. 看起来像这样:

    {if ($1 >= 01001 && $1 <=01936) 
    print "Sachsen" >"PLZ6.txt"} 
    {if ($1 >= 01941 && $1 <= 01998) 
    print "Brandenburg" >"PLZ6.txt"}
    {if ($1 >= 02601 && $1 <= 02999)
    print "Sachsen" >"PLZ6.txt"}
    {if ($1 >= 03001 && $1 <= 03253)
    print "Brandenburg" >"PLZ6.txt"} #this goes on for another 150 different lines...
    

    所以我认为我只得到一个邮政编码的名称(如果它属于条件的范围)。这意味着我的新文件中应该有2267个案例。但是,我的新文件为23k案例。

    我想知道,如果邮政编码属于多个范围......你有什么想法,为什么邮政编码可以适应几种情况?我想让每个邮政编码完全匹配一个条件。

3 个答案:

答案 0 :(得分:6)

由于我不知道整个脚本或整个输入数据,因此很难肯定地说,但我强烈怀疑它与您无意中使用八进制数有关。在awk中,以0开头并且不包含89的文字是八进制数,也就是说010 == 80100 == 64有关详细信息,请参阅here

写作时

{if ($1 >= 01001 && $1 <=01936)

然后01001是八进制数,01936是十进制数(至少有GNU awk,因为它包含9),所以你要问是否$1 >= 513 && $1 <= 1936

我怀疑你以这种方式构建了重叠范围,并且可以通过从所有条件中删除前导零来解决问题(因为八进制解释不适用于输入数据)。

顺便说一下,编写

可能会更加愚蠢
$1 >= 1001 && $1 <= 1936 { print "Sachsen" > "PLZ6.txt" }

等等。

答案 1 :(得分:2)

@Wintermute可能是八进制猜测正确的。如果是这样接受他的回答,但无论哪种方式都将你的代码重写为:

function m(beg,end,state) {
    if ( ($1 >= beg) && ($1 <= end) ) {
        if ($1 in states) {
            printf "Warning: State for zip \"%s\" being changed from \"%s\" to \"%s\".\n", $1, states[$1], state| "cat>&2"
        }
        states[$1] = state
        print state > "PLZ6.txt"
    }
}
{
    m(1001,1936,"Sachsen") 
    m(1941,1998,"Brandenburg")
    m(2601,2999,"Sachsen")
    m(3001,3253,"Brandenburg")
}

一旦您确定并修复了邮政编码的任何剩余问题,请在next功能的末尾添加m()语句,以显着提高代码效率:

function m(beg,end,state) {
    if ( ($1 >= beg) && ($1 <= end) ) {
        if ($1 in states) {
            printf "Warning: State for zip \"%s\" being changed from \"%s\" to \"%s\".\n", $1, states[$1], state| "cat>&2"
        }
        states[$1] = state
        print state > "PLZ6.txt"
        next
    }
}

答案 2 :(得分:0)

如果我是对的,那么包含邮政编码的文件应该如下所示:

01001 City-Name Sachsen
01936 City-Name Sachsen
02601 City-Name Sachsen
02602 City-Name Sachsen
02603 City-Name Sachsen
02604 City-Name Sachsen
02999 City-Name Sachsen
01941 City-Name Brandenburg
01942 City-Name Brandenburg
01943 City-Name Brandenburg
01944 City-Name Brandenburg
01945 City-Name Brandenburg
01998 City-Name Brandenburg
03001 City-Name Brandenburg
03253 City-Name Brandenburg

此处将City-Name替换为邮政编码的实际城市名称。要获得该密码的联邦状态,您可以进行简单的模式搜索,如

$ awk '/01945/ {print $3}' postalcodes.txt
Brandenburg

这应该给你联邦政府。这解决了你的问题吗?