次のスクリプト:
DYN_HOSTS_START_ARRAY=($(grep -E "STARTING HOST" sample.log | cut -d' ' -f 1,2))
for ((i=0; i< ${#DYN_HOSTS_START_ARRAY[@]}; i++))
do
echo "$i: start: "${DYN_HOSTS_START_ARRAY[$i]}""
done
次のサンプル .log ファイルを使用します。
2019-11-11 19:05:55,823 DEBUG STARTING HOST 46
2019-11-11 19:05:55,831 DEBUG STARTING HOST 703
2019-11-11 19:05:55,837 DEBUG STARTING HOST 505
2019-11-11 19:05:55,858 DEBUG STARTING HOST 93
2019-11-11 19:05:55,859 DEBUG STARTING HOST 486
2019-11-11 19:05:55,861 DEBUG STARTING HOST 72
2019-11-11 19:05:55,879 DEBUG STARTING HOST 855
2019-11-11 19:05:55,913 DEBUG STARTING HOST 560
2019-11-11 19:05:56,067 DEBUG STARTING HOST 199
次のような不要な出力が生成されます。
0: start: 2019-11-11
1: start: 19:05:55,823
2: start: 2019-11-11
3: start: 19:05:55,831
4: start: 2019-11-11
5: start: 19:05:55,837
6: start: 2019-11-11
7: start: 19:05:55,858
8: start: 2019-11-11
9: start: 19:05:55,859
10: start: 2019-11-11
11: start: 19:05:55,861
12: start: 2019-11-11
13: start: 19:05:55,879
14: start: 2019-11-11
15: start: 19:05:55,913
16: start: 2019-11-11
17: start: 19:05:56,067
必要な出力には18個ではなく9個の要素のみを含める必要があり、各要素には生の空白で区切られた日時が含まれます。
アレイの初期化を維持しながらスクリプトを変更するにはどうすればよいですか?たった9つの要素、これを達成するには?
答え1
mapfile -t
次のように、プロセス置換でデータを使用して読み取ることができます。@クサラナンダ指摘した。
mapfile -t dyn_hosts_start_array < <(grep 'STARTING HOST' sample.log | cut -d' ' -f 1,2)
for i in "${!dyn_hosts_start_array[@]}"; do
printf '%s: start: %s\n' "$i" "${dyn_hosts_start_array[i]}"
done
または、IFS
単語の区切りに使用される変数を改行文字(デフォルトはスペース、タブ、および改行文字)に変更してから、元の値に戻すこともできます。
oldifs=$IFS
IFS=$'\n'
dyn_hosts_start_array=( $(grep 'STARTING HOST' sample.log | cut -d' ' -f 1,2) )
IFS=$oldifs
for i in "${!dyn_hosts_start_array[@]}"; do
printf '%s: start: %s\n' "$i" "${dyn_hosts_start_array[i]}"
done
出力(2つのバリエーション):
0: start: 2019-11-11 19:05:55,823
1: start: 2019-11-11 19:05:55,831
2: start: 2019-11-11 19:05:55,837
3: start: 2019-11-11 19:05:55,858
4: start: 2019-11-11 19:05:55,859
5: start: 2019-11-11 19:05:55,861
6: start: 2019-11-11 19:05:55,879
7: start: 2019-11-11 19:05:55,913
8: start: 2019-11-11 19:05:56,067
関連:
答え2
awk '{print NR-1 ": ", "start:", $1, $2;}' sample.log
質問に印刷された入力を使用してください。
0: start: 2019-11-11 19:05:55,823
1: start: 2019-11-11 19:05:55,831
2: start: 2019-11-11 19:05:55,837
3: start: 2019-11-11 19:05:55,858
4: start: 2019-11-11 19:05:55,859
5: start: 2019-11-11 19:05:55,861
6: start: 2019-11-11 19:05:55,879
7: start: 2019-11-11 19:05:55,913
8: start: 2019-11-11 19:05:56,067
出力形式をより効果的に制御するには、次のものを使用することもprintf
できます。
awk '{printf "%d: start: %s %s\n", NR-1, $1, $2;}' sample.log
コマンドの置き換えには、スペースや特殊文字がある場合はいくつかの欠点があります。明らかに、入力の2つのフィールドは別々の配列要素に保持される。このスクリプトは、元のスクリプトに基づいてそれらを結合します。
DYN_HOSTS_START_ARRAY=($(grep -E "STARTING HOST" sample.log | cut -d' ' -f 1,2))
for ((i=0; i< ((${#DYN_HOSTS_START_ARRAY[@]} / 2)); i++))
do
echo "$i: start: ${DYN_HOSTS_START_ARRAY[((2 * $i))]} ${DYN_HOSTS_START_ARRAY[((2 * $i + 1))]}"
done