質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

AWK

AWKは、UNIX 上で開発されたプログラミング言語で、CSVファイルなどのテキストファイルの処理を目的にデザインされています。

Q&A

解決済

2回答

6530閲覧

Bashスクリプト 配列最後の要素を抜き出す

minhouse10

総合スコア41

bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

AWK

AWKは、UNIX 上で開発されたプログラミング言語で、CSVファイルなどのテキストファイルの処理を目的にデザインされています。

0グッド

0クリップ

投稿2017/12/18 16:43

編集2017/12/19 15:37

whileループの中で、値に応じて異なる変数や配列に格納する処理を行っていますが、数字一文字3の場合だけ特別に追加処理が必要なため一旦最初のIF文では全ての数字を配列に格納した後、次のELIFの処理にて最初のIF文で格納した配列の最後の要素をチェックさせその数字が3であった場合は別処理用の別変数と別配列に格納する処理を行いたいと思っておりますが以下のエラーが発生してしまいます(比較演算子を-eq, =としても結果は同じ)。上手く配列の最後の要素を参照する方法をご存知の方、ご教授の程よろしくお願いいたします。

cal.sh: line 17: [: =: unary operator expected
cal.sh: command substitution: line 20: syntax error: unexpected end of file

入力するテキストファイルresult.logには以下のようにランダムな数字が並び、最後の行に3があります。

53

219

3

rfile='/Backup/monitor/result.log' declare -a r_count=() declare -a no_eps=() cnt=0 r_chk=0 while read line || [ -n "${line}" ]; do if [ `(echo "${line}" | grep -o '^[0-9]*$')` ];then cnt=`expr "${cnt}" + 1` r_count+=("$line") line17: elif [ `(echo "${r_count[@]}" |awk '{print $(NF)}')` = 3 ];then r_chk=`expr "${r_chk}" + 1` r_host=`(echo "${line}" |awk '{print $6}'` no_eps+=("$r_host") fi done < $rfile

あちこちマスクしていますが、修正版のスクリプトです。

#!/bin/bash rfile='/Backup/result.log' declare -a count=() declare -a lost_rs=() declare -a no_ps=() declare -a all_host=() cnt=0 cnt1=0 r_chk=0 while read line || [ -n "${line}" ]; do if [ `(echo "${line}" |grep -o 'IP')` ];then aep=`(echo "${line}" |awk -F ' ' '{print $2}' )` all_host+=("${aep}") fi if [ `(echo "${line}" | grep -o '^[0-9]*$')` ];then cnt=`expr "${cnt}" + 1` rpl_count+=("${line}") mng=`echo ${count[${#count[@]}-1]}` elif [ `(echo "${line}" | grep -o 'SSH')` ];then cnt1=`expr "${cnt1}" + 1` line=`(echo "${line}" |awk '{print $2}')` lost_crs+=("${line}") fi if [ "${mng}" = '3' ];then mng=`echo ${all_host[${#all_host[@]}-1]}` no_eps+=("${mng}") fi done < $rfile #echo "This is ${all_host[@]}" for item in ${count[@]};do if [ "${item}" = '3' ];then r_chk=`expr "${r_chk}" + 1` fi done non_ep=$(($cnt * 3)) total=0 n=${#count[@]} n=$((n - 1)) while [ "${n}" -ge 0 ]; do total=$((count[$n] + $total)) r_total=$(($total - $non_ep)) n=$((n - 1)) done echo "Total Count = $r_total" total_cr=`expr "${cnt}" + "${cnt1}"` con_rate=`echo "scale=2; 1-($cnt1/$cnt)" | bc` con_rate2=`echo "scale=2; $con_rate*100" | bc` echo "Connection Rate = $con_rate2 %" echo "Number of Connected = $cnt" echo -e "\n" echo -e "Number without Ps = $r_chk" echo -e " -without Ps-\n ${no_es[@]}" echo -e "\n" echo "Number of Lost = $cnt1" #echo -e "\n" if [ "${cnt1}" -gt 0 ];then echo -e " -Lost Connection-\n ${lost_rs[@]}" else echo " -All Connected-" fi

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

スクリプトがあちこちおかしいと思いますが、仕様が明確じゃないので、どう直せばいいか分かりません。

とりあえず、配列変数の最後の要素と言う事にだけ答えると、

Bash

1a=(q w e r t y) 2echo 最後の要素は ${a[${#a[@]}-1]} 3 4a=(q w e r t y) 5for last in "${a[@]}" 6do : 7done 8echo 最後の要素は ${last}

なお、Bashのバージョンによっては、${a[-1]}で良いようです。4.1.2では駄目でした。

投稿2017/12/19 01:15

編集2017/12/19 01:39
otn

総合スコア84529

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

minhouse10

2017/12/19 02:31

otn様、ご教授頂きありがとうございます。配列の一番最後を抜き出すための方法は知らなかったので、非常に勉強になります。アドバイスいただいた方法で再度テストし実行結果を共有させて頂きます。
minhouse10

2017/12/19 15:33

otn様、ご教授頂きました方法で、正常に配列の最後の値を抜き出すことができ、期待通りの結果が得られました。改めて本当にありがとうございました。とても勉強になりました。(まだまだ無駄の多いスクリプトですが、修正版のスクリプトを恥ずかしながら投稿させて頂きました)
guest

0

入力元ファイルにおいて数字は一行おきに入っているようですが、そうだとすると空行を読み込んだ時に[ ]の中が文法的に破綻してしまうのではないでしょうか?

投稿2017/12/18 16:53

編集2017/12/18 16:53
KojiDoi

総合スコア13671

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

minhouse10

2017/12/19 02:28

KojiDoi様、ご教授頂きありがとうございます。スクリプト実行時にデバッグモードで処理を見ると一応問題なく空行も処理されているようです。もう一旦問題がないかスクリプトの内容を確認してみたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問