2017-10-18 155 views
0

此腳本不完整,因爲我稍後想要做錯誤測試,但想法是ARG是腳本,ARG2是目錄,ARG應標記ARG2中的所有文件。我該如何做到這一點,讓bash知道第一個參數必須是腳本,而參數2是一個目錄?將腳本作爲參數傳遞Bash

ARG=$1 
ARG2=$2 
CHECK=0 
aCount=0 
bCount=0 
cCount=0 
dCount=0 
fCount=0 

if [ $CHECK -e 0 ]; then 
    for files in $ARG2; do 
     if [ sh $1 $2 -eq A]; then 
      aCount=$((aCount+1)) 
     elif [ sh $1 $2 -eq B]; 
      bCount=$((bCount+1)) 
     elif [ sh $1 $2 -eq C]; 
      cCount=$((cCount+1)) 
     elif [ sh $1 $2 -eq D ]; 
      dCount=$((dCount+1)) 
     else; 
      fCount=$((fCount+1)) 
     fi 
    done 
fi 

echo A: $aCount 
echo B: $bCount  
echo C: $cCount   
echo D: $dCount 
echo F: $fCount 

回答

4

有很多種,你可以通過運行腳本通過shellcheck.net捕獲錯誤的。

更正:

  • 循環遍歷目錄中的文件,寫for file in dir/*for file in dir。後者只是循環一次,$file設置爲字符串"dir",而不是遍歷目錄dir/的內容。

  • [ sh $1 $2 -eq A]是shell構造的混亂。你想捕獲腳本的輸出,所以你需要$(...)。您正在進行字符串檢查,因此您應該使用==而不是-eq。糾正這兩種收益:

    [ $(sh $1 $2) == A ] 
    
  • 我猜$2$files,雖然。循環變量,是嗎?

    [ $(sh $1 $files) == A ] 
    
  • 還有其他一些雜項錯誤,如缺少then S和]以前並不總是有空間。

改進:

  • 你應該合理報價一切以防止意外的分詞和水珠擴張。

    [ "$(sh "$1" "$files")" == A ] 
    
  • 讓我們更換$1$script$files與奇異$file

    [ "$(sh "$script" "$file")" == A ] 
    
  • 如果腳本有適當的家當線像#!/bin/bash頂部則沒有必要明確地調用sh

    [ "$("$script" "$file")" == A ] 
    
  • 這一切都很棒。現在你有這樣的事情:

    if [ "$("$script" "$file")" == A ]; then 
        aCount=$((aCount+1)) 
    elif [ "$("$script" "$file")" == B ]; then 
        bCount=$((bCount+1)) 
    elif [ "$("$script" "$file")" == C ]; then 
        cCount=$((cCount+1)) 
    elif [ "$("$script" "$file")" == D ]; then 
        dCount=$((dCount+1)) 
    else 
        fCount=$((fCount+1)) 
    fi 
    

    非常重複,不是嗎?我們來試試case聲明。

    case "$("$script" "$file")" in 
        A) aCount=$((aCount+1));; 
        B) bCount=$((bCount+1));; 
        C) cCount=$((cCount+1));; 
        D) dCount=$((dCount+1));; 
        *) fCount=$((fCount+1));; 
    esac 
    
  • 該案例陳述仍然相當複雜。讓我們分解它以便更容易解析。

    grade=$("$script" "$file") 
    
    case $grade in 
        ... 
    esac 
    
  • 變量名應該是小寫。大寫的名字是爲shell保留的,所以最好不要使用它們。將COUNT更改爲count

  • 讓我們將ARGARG2分別重命名爲scriptdir。有意義的名稱使所有內容更易於閱讀。可以簡化爲((var += 1))((var++))

最終結果:

script=$1 
dir=$2 

check=0 
aCount=0 
bCount=0 
cCount=0 
dCount=0 
fCount=0 

if ((check == 0)); then 
    for file in "$dir"/*; do 
     grade=$("$script" "$file") 

     case $grade in 
      A) ((aCount++));; 
      B) ((bCount++));; 
      C) ((cCount++));; 
      D) ((dCount++));; 
      *) ((fCount++));; 
     esac 
    done 
fi 

echo "A: $aCount" 
echo "B: $bCount" 
echo "C: $cCount" 
echo "D: $dCount" 
echo "F: $fCount" 
+0

沒關係,我想通了。非常感謝你:) – DrJessop

2

@John Kugelman上面做一個偉大的工作。替代拍 -

declare -A count     # count is an array 
for file in "$dir"/*    # skipping assignments, and $check 
do grade=$("$script" "$file")  # grab the output as $grade 
    case $grade in     # look up its value 
    [A-D]) ((count[$grade]++));; # use as-is for a-d 
     *) ((count['F']++ ));; # throw everything else in f 
    esac 
done 

for g in A B C D F     # then for a-f (known values) 
do echo "$g: "${count[$g]}   # pull the counts 
done 
+0

一個數組是一個好主意。我的回答中空間用完了。 ;) –

+1

你會希望爲關聯數組聲明-A。 –

+0

我*有*'-A',並開始測試一些選項,最終沒有放回去。謝謝,編輯/更正。 –