在数字序列中搜索缺失的数字

Jaw*_*per 6 text-processing

所以我有一个包含大量信息的文件,每个信息“块”都有它自己的唯一标识符,如下所示:

“索引

在linux中使用以下命令后:

$ cat file | grep index
Run Code Online (Sandbox Code Playgroud)

我得到这个结果:

"index": 1
"index": 2
"index": 3
...
"index": 10001
Run Code Online (Sandbox Code Playgroud)

它们之间是一系列连续格式的数字。

那里的某个地方缺少一个号码,我正在尝试找出那个号码。

我尝试了几件事,但没有一个奏效。是否有另一个命令可以添加到它或者是否有更好的方法来搜索丢失的索​​引号?

Edg*_*lon 6

您可以使用diff命令来获取文件与从 N 到 M 的数字序列之间的差异。该awk命令用于解析文本并仅获取数字:

diff --side-by-side --suppress-common-lines  <(awk '{print $2}' file.txt) <(seq 1 10001) | awk '{print $2}'
Run Code Online (Sandbox Code Playgroud)

上面的代码将文件的编号与 from1到 的序列进行比较10001

要以更实用的方式来实现此目的,您可以检测文件的最后一个数字(10001)并将其分配给一个变量:

max=$(tail -1 file.txt | awk '{print $2}')
diff --side-by-side --suppress-common-lines  <(awk '{print $2}' file.txt) <(seq 1 $max) | awk '{print $2}'
Run Code Online (Sandbox Code Playgroud)

例如,有这样的:

文件.txt

"index": 1
"index": 5
"index": 8
"index": 9
"index": 10
"index": 12
"index": 13
"index": 15
Run Code Online (Sandbox Code Playgroud)
"index": 1
"index": 5
"index": 8
"index": 9
"index": 10
"index": 12
"index": 13
"index": 15
Run Code Online (Sandbox Code Playgroud)

输出:

2
3
4
6
7
11
14
Run Code Online (Sandbox Code Playgroud)

顺便说一句,如果您想以这种格式打印缺失值:"index": the_missing_number您可以更改最后awk print一条语句,如下所示:

max=$(tail -1 file.txt | awk '{print $2}')
diff --side-by-side --suppress-common-lines  <(awk '{print $2}' file.txt) <(seq 1 $max) | awk '{print $2}'
Run Code Online (Sandbox Code Playgroud)


jub*_*us1 1

使用Raku(以前称为 Perl_6)

\n
~$ raku -e \'my @a; for lines() {@a.push: $/.Int if .match(/<?after \\"index\\"\\: \\s > \\d+ /) };  \\\n            put ((1..10) (-) @a.Set).keys.sort;\'  index.txt\n\n#OR\n\n~$ raku -e \'my @a; for lines() {@a.push: $0.Int if .match(/<?after \\"index\\"\\: \\s > (\\d+) /) };  \\\n            put ((1..10) (-) @a.Set).keys.sort;\'  index.txt\n
Run Code Online (Sandbox Code Playgroud)\n

Raku 是 Perl 家族的一种编程语言。它于 2015 年作为 Perl_6 发布,并于 2019 年更名为 Raku。因此,您会在 Raku 中发现许多“Perl 主义”。

\n

Raku 的一项有趣功能是集合语义。Unicode 和 ASCII 运算符均可用。在上面的代码中,ASCII(-)代表集合差值(非对称)。您还可以使用 Unicode:

\n
\xe2\x88\x96\nSET MINUS\nUnicode: U+2216, UTF-8: E2 88 96\n
Run Code Online (Sandbox Code Playgroud)\n

示例输入(注意最大值为 100):

\n
"index": 1\n"index": 2\n"index": 3\n"index": 5\n"index": 100\n
Run Code Online (Sandbox Code Playgroud)\n

示例输出(两个代码示例):

\n
4 6 7 8 9 10\n
Run Code Online (Sandbox Code Playgroud)\n

警告:对称和非对称 Set 操作很容易混淆。例如,对于上面的代码,如果您颠倒集合的顺序并尝试使用 ASCII(^)或 Unicode\xe2\x8a\x96 对称集合差异运算符,您将看到很大的差异(用作1..99测试范围):

\n
~$ cat index.txt | perl6 -e \'my @a = do for lines() {$/.Int if .match(/<?after \\"index\\"\\: \\s > \\d+ /) }; put (@a.Set (-) (1..99)).keys.sort;\'\n100\n~$ cat index.txt | perl6 -e \'my @a = do for lines() {$/.Int if .match(/<?after \\"index\\"\\: \\s > \\d+ /) }; put (@a.Set (^) (1..99)).keys.sort;\'\n4 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100\n
Run Code Online (Sandbox Code Playgroud)\n

https://docs.raku.org/language/setbagmix
\n https://raku.org

\n