다음 스크립트:
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
출력(두 가지 변형):
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