2017-08-07 61 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格式轉換。