以下脚本:
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
所需输出应仅包含 9 个元素(而不是 18 个),每个元素包含日期和时间,并由原始空格分隔。
如何修复我的脚本,同时保留数组初始化,仅 9 个元素,以实现这一点?
答案1
您可以使用mapfile -t
并读取流程替换中的数据,如下所示@Kusalananda指出。
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
输出(两种变体):
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
命令替换在空格或特殊字符方面存在一些缺陷。显然,输入中的两个字段保存在单独的数组元素中。该脚本根据您的原始脚本将它们组合起来。
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