以下のように何百もの行がありますconnRefused.log
。
2015-12-12 00:12:10,227 ERROR [Testing-KeepAlive-01] c.v.v.v.Connection [Connection.java : 001] failed to bind to {name=TestGW,direction=BOTH_WAY,username=espada,password=whatever,binds=1,keepAliveInterval=60000,params={Payload=0, useEXP=1},thisOne={id=1001,name=TestGw,ip=192.168.0.1,port=88}}: Connection refused
connRefused.log
以下は、配列を読み取るための私のスクリプト(簡体字)の一部です。
IFS=$'\n' read -d '' -r -a lines < /path/log/connRefused.log
for xx in "${lines[@]}"
do
??? # what to do here?
echo $Date
echo $ID
echo $Name
echo $IP
echo $Port
done
上記の行から必要なデータを取得し、日付、ID、名前、IP、ポート変数に保存するにはどうすればよいですか?
thisOne={id=1001,name=TestGw,ip=192.168.0.1,port=88}
。
$Dateの場合、時間部分のみが必要です。
答え1
配列を使用する必要はありません。入力データが非常に規則的に見えるので、入力データをシェル割り当てステートメントに変換し、それをシェルに読み込んで計算します。このように:
#!/bin/sh
sed '
s/^[-0-9]* */date=/
s/,.*thisOne={/ /
s/}.*//
s/,/ /g
' "$@" |
while read line
do
eval $line
echo date=$date
echo id=$id
echo name=$name
echo ip=$ip
echo port=$port
done
このsed
コマンドは入力ラインを次に変換します。
date=00:12:10 id=1001 name=TestGw ip=192.168.0.1 port=88
ループwhile
は一度に1行を読み取り、その行をシェルeval $line
で実行し、変数を与えられた値に設定します。
スクリプトはコマンドラインまたは標準入力からファイル名を処理します(コマンドの"$@"
末尾に.があることに注意してくださいsed
)。
このコマンドは、sed
一連の(代替)コマンドを介してs
行をシェル割り当てステートメントに変換します。
行の先頭()でのみダッシュと数字()の後に1つ以上のスペース()が続く
^
順序を次に置き換えます。[-0-9]*
*
date=
s/^[-0-9]* */date=/
カンマ
.*
の後にランダムな文字()とスペースが続く場合は置き換えます。thisOne=
s/,.*thisOne={/ /
閉じる中括弧()を削除し、行の(暗黙的な)末尾に
}
他の文字()を削除します。.*
s/}.*//
すべてのカンマ(
,
)を空白に置き換えます。s/,/ /g
|
サンプルスクリプトでは、ファイルの末尾にあるパイプを一時的に削除し、スクリプトのコマンドsed
部分のみを実行してどのように機能するかを試すことをお勧めします。