予期しないタグ「else」の近くに構文エラーがあります。

予期しないタグ「else」の近くに構文エラーがあります。

ステータス情報やその他のさまざまなテキストで埋められたtxtファイルの特定の部分を削除するスクリプトを作成しようとしています。主なif文を終了できません。さらに、output.txtを生成するスクリプトにdateコマンドを入れて、最も古い状態情報を削除しようとしました。最も古い情報を削除する方法はありますか?私は主にif文を終了したいと思います。ありがとうございます。 (また、もともとelse ifをelifとして使用しましたが、結果は同じでした。)

./count.sh: 行 30:else' ./count.sh: line 30:予期しない表示の近くで構文エラーが発生しました。

WCOUNT=$(wc -l output.txt $1 | awk '{print $1}')

if [[ $WCOUNT -gt 50 ]]; then 

    if [[ "grep CLIENTSTART output.txt" != null ]]; then
        echo $WCOUNT
        sed -i '/\*\*\*CLIENTSTART/,/CLIENTEND\*\*\*/ d' output.txt
        echo $WCOUNT

    else if [[ -n "grep DHCPSTART output.txt" ]]; then          

        echo $WCOUNT
        sed -i '/\*\*\*DHCPSTART/,/DHCPEND\*\*\*/ d' output.txt     
        echo $WCOUNT

    else if [[ -n "grep DNSSTART output.txt" ]]; then
        echo $WCOUNT
        sed -i '/\*\*\*DNSSTART/,/DNSEND\*\*\*/ d' output.txt
        echo $WCOUNT

    else if [[ -n "grep WEBSTART output.txt" ]]; then
        echo $WCOUNT
        sed -i '/\*\*\*WEBSTART/,/WEBEND\*\*\*/ d' output.txt
        echo $WCOUNT

    else
        echo "Cannot help you"
    fi

else
    echo "You're good, homie.  It's under 500"

fi

答え1

ここでの問題は、else if代わりにを使用すると、elifプログラムに入れ子が追加され、追加のfi条件文を終了するためにさらにステートメントを追加する必要があることです。

以下は、私が何を意味するのかを示すために少し異なるインデントを含むプログラムの編集版です。

WCOUNT=$(wc -l output.txt $1 | awk '{print $1}')

if [[ $WCOUNT -gt 50 ]]; then 
    if [[ "grep CLIENTSTART output.txt" != null ]]; then
        echo $WCOUNT
        sed -i '/\*\*\*CLIENTSTART/,/CLIENTEND\*\*\*/ d' output.txt
        echo $WCOUNT
    else 
        if [[ -n "grep DHCPSTART output.txt" ]]; then          
            echo $WCOUNT
            sed -i '/\*\*\*DHCPSTART/,/DHCPEND\*\*\*/ d' output.txt     
            echo $WCOUNT
        else 
            if [[ -n "grep DNSSTART output.txt" ]]; then
                echo $WCOUNT
                sed -i '/\*\*\*DNSSTART/,/DNSEND\*\*\*/ d' output.txt
                echo $WCOUNT
            else 
                if [[ -n "grep WEBSTART output.txt" ]]; then
                    echo $WCOUNT
                    sed -i '/\*\*\*WEBSTART/,/WEBEND\*\*\*/ d' output.txt
                    echo $WCOUNT
                else
                    echo "Cannot help you"
                fi
            fi
        fi
    fi
else
    echo "You're good, homie.  It's under 500"

fi

または、次のものを使用できます。elif

WCOUNT=$(wc -l output.txt $1 | awk '{print $1}')

if [[ $WCOUNT -gt 50 ]]; then 

    if [[ "grep CLIENTSTART output.txt" != null ]]; then
        echo $WCOUNT
        sed -i '/\*\*\*CLIENTSTART/,/CLIENTEND\*\*\*/ d' output.txt
        echo $WCOUNT

    elif [[ -n "grep DHCPSTART output.txt" ]]; then          

        echo $WCOUNT
        sed -i '/\*\*\*DHCPSTART/,/DHCPEND\*\*\*/ d' output.txt     
        echo $WCOUNT

    elif [[ -n "grep DNSSTART output.txt" ]]; then
        echo $WCOUNT
        sed -i '/\*\*\*DNSSTART/,/DNSEND\*\*\*/ d' output.txt
        echo $WCOUNT

    elif [[ -n "grep WEBSTART output.txt" ]]; then
        echo $WCOUNT
        sed -i '/\*\*\*WEBSTART/,/WEBEND\*\*\*/ d' output.txt
        echo $WCOUNT

    else
        echo "Cannot help you"
    fi

else
    echo "You're good, homie.  It's under 500"

fi

(また、少しトリッキーに言えば、50行以上の行があるかどうかを確認していますが、出力メッセージには500行をチェックすると言われています。技術的には500行未満の行がありますが、これは少し誤解を招く可能性があります。p)

編集:他の人が指摘したように、これは構文エラーを解決しますが、スクリプトにはまだ他の問題があります。私も彼らのコメント/回答を読むことをお勧めします。

答え2

構文エラーが発生する理由はステートメントelse ifですelif

2つのファイルが提供されると、wc -l3行の出力が生成されます。

$ wc -l .profile .profile
      30 .profile
      30 .profile
      60 total

これは引用符のない最初のifテストに影響し、$WCOUNT拡張時に別の構文エラーが発生します。

欲しいかもしれません

WCOUNT=$( wc -l <output.txt )

また、文字列に関するいくつかのテストがあります"grep DHCPSTART output.txt"いつもそれは真実だ。

ファイルに文字列があるかどうかをテストするには、次のようにします。

if grep -Fq 'fixed string' filename; then

例えば

if grep -Fq 'CLIENTSTART' output.txt; then
   # do something
elif grep -Fq 'DHCPSTART' output.txt; then
   # do something
else
   # do something
fi

実際の出力生成を停止します-qgrep終了ステータスは、文字列が見つかったかどうかを示し、これがifこのステートメントを機能させるようにします(フラグはまた、最初の一致でgrepファイルの読み取りを停止することを可能にします)。この-Fフラグを使用すると、grep指定されたパターンは正規表現ではなく固定文字列として扱われます。


スクリプト内部構造の提案:

tmpfile=$(mktemp)

for string in CLIENT DHCP DNS WEB; do
    if grep -Fq "${string}START" output.txt; then
        sed "/\*\*\*${string}START/,/${string}END\*\*\*/d" \
            output.txt >"$tmpfile"
        break
    fi
done

if [ -s "$tmpfile" ]; then
    mv "$tmpfile" output.txt
else
    echo 'Can not help you'
    rm -f "$tmpfile"
fi

[ -s "$tmpfile" ]ファイル$tmpfileサイズが0より大きい場合(呼び出し時のサイズ)、テストはsed成功します。

forbreakロジックを模倣しますif ... then ... elifが、より簡潔な方法でループを使用します。

関連情報