2015-12-03 108 views
0

我有一个脚本以下AWK语句工作。但是,如果我运行以下操作:AWK不bash脚本

grep -E Toronto listing.dat | awk -F "[\t]+" '($3 >= 2) && ($4 >= 500) && ($5 <= 900000) && ($6 <= 10)' listing.dat | sort -nk4 | less 

它按预期输出。

我不知道为什么会发生这种情况,我甚至已经替换了脚本中的awk语句来回显变量以确保它们正确传递并且它们是。

这是迄今为止该脚本:

#!/bin/bash 

    DATFILE=listing.dat 

    if [ -f ${DATFILE} ]; 
    then 

      echo -n "Are you looking into anywhere in the GTA, or a specific city?: " 
      read uinput 

      if [ $uinput == "anywhere" ]; 
      then 
        echo "You have chosen anywhere" 
      elif [ $uinput == "specific" ]; 
      then 
        echo -n "Which city?: " 
        read city 

        echo -n "Minimum Number of Bedrooms: " 
        read minbed 

        echo -n "Minimum Square Footage (500, 600, etc): " 
        read minsqft 

        echo -n "Maximum Price: " 
        read maxprice 

        echo -n "Maximum Weeks On Market: " 
        read maxweeks 

        echo -n "Sort by (price, sqrft, weeks): " 
        read sortby 

        if [ $sortby == "price" ]; 
        then 
          echo -n "Sort by (asc, desc): " 
          read ascdesc 
          if [ $ascdesc == "asc" ]; 
          then 
            grep -E $city $DATFILE | awk -F "[\t]+" '($3 >= $minbed) && ($4 >= $minsqft) && ($5 <= $maxprice) && ($6 <= $maxweeks)' $DATFILE | sort -nk5 | less 
         elif [ $ascdesc == "desc" ]; 
         then 
           grep -E $city $DATFILE | awk -F "[\t]+" '($3 >= $minbed) && ($4 >= $minsqft) && ($5 <= $maxprice) && ($6 <= $maxweeks)' $DATFILE | sort -rnk5 | less 
         fi 
       fi 

     fi 

else 
     echo "${DATFILE} Not found!" 
fi 

能否请你帮忙吗?

感谢

+1

'gawk'或'awk'?你的例子中都有。 – miken32

+3

您的awk脚本使用单引号。当它们位于引号引号内时,Shell变量不会被展开。所以您需要使用-v将它们分配给awk变量。 –

+1

无论如何,请勿将grep结果传递给awk。 awk本身能够通过正则表达式来过滤 – hek2mgl

回答

2

如果新来的任何* nix的工具,你可以看到使用'人utility_name的基本文档;从手册页 'AWK'(人AWK):

-v VAR = VAL
分配值VAL到变量var中,程序的执行开始之前。这些变量值可用于AWK程序的BEGIN块 。

还有其他的方法可以做到这一点,但遵照docs您的代码将改为类似:

awk -F "[\t]+" \ 
    -v MINBED=$minbed -v MINSQFT=$minsqft -v MAXPRICE=$maxprice -v MAXWEEKS=$maxweeks \ 
    '($3 >= MINBED) && ($4 >= MINSQFT) && ($5 <= MAXPRICE) && ($6 <= MAXWEEKS)' 
+0

好吧,这是伟大的。它完美的工作,但我无法通过城市现在过滤。在脚本和管道中使用egrep,它可以显示所有城市。如果我从脚本中直接运行相同的命令并直接进入终端,它就会起作用....任何想法? –

+0

从awk命令字符串中删除'$ DATAFILE'; grep中的'pipe'(匹配)直接发送到'awk' - 'awk'将打印文件中的所有内容,如果包含文件名... [它忽略'pipe'中的数据] ... –

0

我不能尚未就此发表评论,由于声誉。你可以做的另一件事是围绕你的变量名称单引号。如果您仍然遇到所有显示的城市出现问题,我相信这是因为您正在向awk提供文件名。它看起来像你需要把它拿出来,让grep的输出作为awk的输入。我没有访问我的Linux机器测试,但:

您的线路(已$ DATFILE提供两次):

grep -E $city $DATFILE | awk -F "[\t]+" '($3 >= $minbed) && ($4 >= $minsqft) && ($5 <= $maxprice) && ($6 <= $maxweeks)' $DATFILE; 

选项1:删除第二个$ DATFILE,逃单引号

grep -E $city $DATFILE | awk -F "[\t]+" '($3 >= '$minbed') && ($4 >= '$minsqft') && ($5 <= '$maxprice') && ($6 <= '$maxweeks')'; 

选项2:您可能完全摆脱grep,使用单引号转义。 awk的IGNORECASE应该是grep -E的替代品。

awk -F "[\t]+" 'IGNORECASE = 1;/'$city'/&&($3 >= '$minbed')&&($4 >= '$minsqft')&&($5 <= '$maxprice')&&($6 <= '$maxweeks')'; 

就像我说的,不能测试它的那一刻语法;我希望它有助于你。

快乐黑客!