案例场景:

$ cat Status.txt
1,connected
2,connected
3,connected
4,connected
5,connected
6,connected
7,disconnected
8,disconnected
9,disconnected
10,disconnected
11,disconnected
12,disconnected
13,disconnected
14,connected
15,connected
16,connected
17,disconnected
18,connected
19,connected
20,connected
21,disconnected
22,disconnected
23,disconnected
24,disconnected
25,disconnected
26,disconnected
27,disconnected
28,disconnected
29,disconnected
30,connected

可以看出,存在“空洞”,将它们理解为序列文件中带有“断开连接”的值的行。

实际上,我想要检测到这些“漏洞”,但是如果我可以在序列中设置缺少数字最小n,这将很有用。
即:对于“n = 5”,可检测到的孔将是7... 13部分,因为序列上的行中至少有5个“断开”。但是,在这种情况下,不应将丢失的17视为可检测到的。再次,在第21行,获得有效的断开连接。

就像是:
$ detector Status.txt -n 5 --pattern connected
7
21

...可以这样解释:
- Missing more than 5 "connected" starting at 7.
- Missing more than 5 "connected" starting at 21.

我需要在 Linux shell 上编写此脚本,因此我正在考虑编写一些循环,解析字符串等程序,但是我觉得是否可以通过使用 linux shell工具以及一些更简单的编程来完成。有办法吗?

即使当像csvtool这样的小程序是有效的解决方案时,在嵌入式设备上工作时,一些更常见的Linux命令(如grepcutawksedwc等)也值得我使用。

最佳答案

#!/usr/bin/env bash
last_connected=0
min_hole_size=${1:-5}  # default to 5, or take an argument from the command line
while IFS=, read -r num state; do
  if [[ $state = connected ]]; then
    if (( (num-last_connected) > (min_hole_size+1) )); then
      echo "Found a hole running from $((last_connected + 1)) to $((num - 1))"
    fi
    last_connected=$num
  fi
done

# Special case: Need to also handle a hole that's still open at EOF.
if [[ $state != connected ]] && (( num - last_connected > min_hole_size )); then
  echo "Found a hole running from $((last_connected + 1)) to $num"
fi

...发出,给定您在stdin(./detect-holes <in.txt)上的文件:

Found a hole running from 7 to 13
Found a hole running from 21 to 29

看到:
  • BashFAQ #1-如何逐行(和/或逐字段)读取文件(数据流,变量)?
  • The conditional expression-[[ ]]语法,用于使其在不引用扩展名的情况下安全地进行字符串比较。
  • Arithmetic comparison syntax-在所有POSIX兼容shell中的$(( ))中有效;也可以将(( ))作为bash扩展而没有扩展副作用。
  • 关于linux - 如何在文本文件中检测到大于n的 “hollows”序列(孔,线与模式不匹配)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48490357/

    10-11 18:22