2017-08-07 60 views
-1

我想遍历一组目录,从文件中读取一行,解析它以分配一个变量的值,然后在变量匹配预定义的字符串时动作。我使用“#!/斌/ bash中运行它。这里是代码。如果环路中没有评估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”时发生。

在此先感谢。

最佳, 萨米特

+1

你的代码有很多问题。通过shellcheck.net运行它来修复明显的问题。 – chepner

+0

你的文件包含DOS风格的行结束符,导致你的字符串有一个尾随回车符('\ r')。您可以通过'tr -d'\ r''管道来去除它。 –

回答

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命令, 并按照我为外部循环做的那样做。

事实上, 如果所有这些echo S和basename s为不是对你非常重要, 和*.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' 
+0

谢谢大家。我一直在关闭这个循环。这最终成为使用和学习bash的开始。几乎所有的答案都按预期工作。清理手术的第一部分可能是最关键的。 –

0

您可以使用DOS2UNIX的处理在众人面前的文件,以UNIX格式转换。