if bash中的循环未被评估

时间:2017-08-07 16:35:57

标签: string bash if-statement

我试图遍历一组目录,从文件中读取一行,解析它以分配变量的值,然后在变量与预定义字符串匹配时执行操作。我正在使用“#!/ bin / bash运行它。这是代码。

23 for DIR in $(find . -name "H[A-Z]*" -maxdepth 1); do
 24   if $(test -d ${DIR}); then
 25     echo $(basename ${DIR});
 26     cd $(basename ${DIR});
 27 
 28     for fname in $(find . -name "*.DAT"); do
 29       echo $(basename $fname);
 30       calType=$(grep 'Level_Unit' $fname | sed -e 's/.*=\([A-Z]\)/\1/');
 31       echo $(basename $calType);
 32         if [ "$calType" == FPL ]
 33         then
 34           echo "This is a keeper " $calType;
 35         fi
 36     done
 37     cd ../
 38 
 39   fi;
 40 
 41 done

我正在将输出转储到我的终端上,这就是我所看到的......

sumit$ ./harp_phaseI_calfilenames.sh 
+ rm harp_Phase1_calnames1.txt
+ touch harp_Phase1_calnames1.txt
+ calTest=FPL
++ find . -name 'H[A-Z]*' -maxdepth 1
+ for DIR in '$(find . -name "H[A-Z]*" -maxdepth 1)'
++ test -d ./HALAF032
++ basename ./HALAF032
+ echo HALAF032
HALAF032
++ basename ./HALAF032
+ cd HALAF032
++ find . -name '*.DAT'
+ for fname in '$(find . -name "*.DAT")'
++ basename ./08E21D00.DAT
+ echo 08E21D00.DAT
08E21D00.DAT
++ grep Level_Unit ./08E21D00.DAT
++ sed -e 's/.*=\([A-Z]\)/\1/'
+ calType=$'V\r'
++ basename $'V\r'
+ echo $'V\r'
V
+ '[' $'V\r' == FPL ']'
+ for fname in '$(find . -name "*.DAT")'

我对这个问题猛烈抨击了一段时间,并且我没有理解为什么在“calType = $'V \ r'”输出底部的六行中有一个美元符号。那么主要的问题是为什么if语句没有被评估......“'''''''V'r'== FPL']'”在底部的第二行。我认识到我提供的实例与变量的字符串不匹配。但是当$ calType为“FPL \ r”时会发生同样的事情。

提前致谢。

最佳, 萨米特

2 个答案:

答案 0 :(得分:0)

您可以使用dos2unix将文件转换为unix格式,然后再处理它们。

答案 1 :(得分:0)

您提出的主要问题似乎与此声明有关:

... | sed -e 's/.*=\([A-Z]\)/\1/'

这将做什么,例如给定输入x=FPLjunk,它将输出FPLjunk。 我的粗略猜测是你要保留大写字母并切掉线末的任何其他内容。 这是实现这一目标的一种方法:

... | sed -e 's/.*=\([A-Z][A-Z]*\).*/\1/'

脚本还有其他令人不安的问题。 我解决了许多突出的问题, 但不是一切。 这相当于更优化和更安全, 我建议研究与原版的不同之处:

shopt -s nullglob

for DIR in "H[A-Z]*"/; do
    echo $(basename "${DIR}")

    for fname in $(find "$DIR" -name "*.DAT"); do
        echo $(basename "$fname")
        calType=$(grep 'Level_Unit' "$fname" | sed -e 's/.*=\([A-Z][A-Z]*\).*/\1/')
        echo $(basename "$calType")
        if [ "$calType" = FPL ]
        then
            echo "This is a keeper " $calType
        fi
    done
done

*.DAT文件可以在嵌套的子目录中吗? 如果没有,最好完全摆脱那里的find命令, 并按照我对外循环的方式进行操作。

事实上, 如果所有echobasename对您来说都不是非常重要, 并且*.DAT文件不在嵌套目录中, 然后整个脚本可以简化为这个单行:

find "H[A-Z]*/" -type f -name "*.DAT" -exec grep Level_Unit + | sed -ne 's/^.*=FPL[^A-Z]*$/This is a keeper FPL/p'