从文件(作为数组)行读取数据并进行比较

Read data from file (as arrays) lines and do a comparison

我有一个问题,不知道使用哪种解决方案更好,我会先描述我的需求,以便向您解释:

我有一个文本文件,标题为服务器名称,例如:server1.txt

在这个文件中我有一些类似数组的东西(基本上它是一个检查结果):

cciex6:~/folder$
cciex6:~/folder$ cat server1
8 16 UP 10-6-2020-16:04
8 16 UP 15-6-2020-16:04
8 16 UP 20-6-2020-16:04
6 16 UP 25-6-2020-16:04
cciex6:~/folder$

8 : 表示 8 个核心

16 :表示 16 Gb 的 ram

UP : 表示 ping 成功,服务器已启动

20-1-2020-16:04 : 检查和创建结果的日期。


我在 servers.txt

中有一些服务器 IP

2 个脚本:

第一个脚本,将对 servers.txt 中的每个服务器进行检查,(检查 cpu 内核、内存、启动或关闭以及日期检查)将此信息存储在 server1 文件中

第二个脚本 应该从 server1 文件中读取行,在新结果(server1 文件中的最后一行)和旧结果(最后一行之前的行)之间做一些比较如果是相同的结果什么都不用做,以防内存增加或服务器宕机,应该在日志文件或控制台或其他东西中给我警报。

第一个脚本已经完成,我可以运行它并从服务器列表中获取我需要的信息

我的问题是第二个脚本,我如何从 server1 文件中读取 RAM + CPU + UP 或 DOWN 状态,并将最后一个结果与最后一个结果之前的结果进行比较,

任何想法请或帮助

非常感谢

取文件的最后两行,然后比较它们,比如。

#!/usr/bin/env bash

file=server1.txt
declare -A old_result new_result
mapfile -t results < <(tail -n2 "$file")

read -r old_core old_ram old_status old_date <<< "${results[0]}"
read -r new_core new_ram new_status new_date <<< "${results[1]}"

old_result=(
  [core]="$old_core"
  [ram]="$old_ram"
  [status]="$old_status"
  [date]="$old_date"
)

new_result=(
  [core]="$new_core"
  [ram]="$new_ram"
  [status]="$new_status"
  [date]="$new_date"
)

for item in "${!old_result[@]}"; do
  [[ $item == date ]] && continue
  if [[ ${old_result[$item]} != ${new_result[$item]} ]]; then
    printf >&2 'old %s and new %s does not match!\n' "$item ${old_result[$item]}" "$item ${new_result[$item]}"
  fi
done
  • 它需要 bash4+,因为 mapfile 和可能的关联数组。

  • 它会跳过日期,但如果您需要比较日期,只需注释掉日期比较或删除该行即可。


只使用没有mapfile的关联数组。

#!/usr/bin/env bash

file=server1.txt
declare -A old_result new_result

{
  read -r old_core old_ram old_status old_date

  old_result=(
    [core]="$old_core"
    [ram]="$old_ram"
    [status]="$old_status"
    [date]="$old_date"
  )

  read -r new_core new_ram new_status new_date

  new_result=(
    [core]="$new_core"
    [ram]="$new_ram"
    [status]="$new_status"
    [date]="$new_date"
  )

} < <(tail -n2 "$file")

for item in "${!old_result[@]}"; do
  [[ $item == date ]] && continue
  if [[ ${old_result[$item]} != ${new_result[$item]} ]]; then
    printf >&2 'old %s and new %s does not match!\n' "$item ${old_result[$item]}" "$item ${new_result[$item]}"
  fi
done

没有mapfile和关联数组,只使用while read循环。

#!/usr/bin/env bash

file=server1.txt

while read -r old_core old_ram old_status old_date; do
  read -r new_core new_ram new_status new_date
  if [[ $old_core != $new_core ]]; then
    printf >&2 'old core %s and new core %s does not match!\n' "$old_core" "$new_core"
  fi
  if [[ $old_ram != $new_ram ]]; then
    printf >&2 'old ram %s and new ram %s does not match!\n' "$old_ram" "$new_ram"
  fi
  if [[ $old_status != $new_status ]]; then
    printf >&2 'old status %s and new status %s does not match!\n' "$old_status" "$new_status"
  fi
done < <(tail -n2 "$file")

should give me alert in a log file or console or something.

将脚本通过管道传输到 wall,它甚至可以通过 cron 调用,它也有一些您可以使用的选项。

似乎您需要做的就是比较最后两行。这是执行此操作的 awk 脚本:

awk ' { 
  line_prev = line_last ; 
   = ""
  line_last = [=10=] 
}
END {
  if (line_prev && line_prev != line_last || line_last ~ /DOWN/ ) { 
    print "Alert!", FILENAME, line_prev, "--->",  line_last
  }
}' ""

脚本,姑且称之为./second_script,可以这样调用:

./second_script server1

您可以将输出通过管道传输到系统日志,以便接收警报。

./second_script server1 | logger "<add-your-favorite-syslog-parameters here>"