如果这是一个简单的问题(或者比我想象的更复杂),我不会以此为生,请原谅我。我一直在挖掘档案,发现很多技巧很接近但是新手我不知道如何调整我的需求,或者他们超出了我的理解。
我有一些大型数据文件,我可以解析它们来生成一个主要是顺序的坐标列表
5
6
7
8
15
16
17
25
26
27
我想要的是间隙列表
1-4
9-14
18-24
我不知道 perl , SQL 或任何花哨的东西,但我想我可以做一些可以减去下一个数字的东西。然后,我可以至少grep
输出差异不是 1 或 -1 的输出,并使用它来获得差距。
答案 0 :(得分:65)
使用awk:
awk '$1!=p+1{print p+1"-"$1-1}{p=$1}' file.txt
$1
是当前输入行的第一列p
是最后一行的前一个值($1!=p+1)
是一个条件:如果$1
与之前的值+1不同,那么:{print p+1 "-" $1-1}
:打印上一个值+1,-
字符和第一列+ 1 {p=$1}
:p
已分配给当前第1列答案 1 :(得分:3)
也许其他人可以为您提供您要求的Bash或Awk解决方案。但是,我认为任何基于shell的答案都可能对您的数据集非常本地化,而且不是很容易扩展。解决Ruby中的问题非常简单,并为您提供灵活的格式化和更多选项,以便在未来的其他方式操作数据集。 YMMV。
#!/usr/bin/env ruby
# You could read from a file if you prefer,
# but this is your provided corpus.
nums = [5, 6, 7, 8, 15, 16, 17, 25, 26, 27]
# Find gaps between zero and first digit.
nums.unshift 0
# Create array of arrays containing missing digits.
missing_nums = nums.each_cons(2).map do |array|
(array.first.succ...array.last).to_a unless
array.first.succ == array.last
end.compact
# => [[1, 2, 3, 4], [9, 10, 11, 12, 13, 14], [18, 19, 20, 21, 22, 23, 24]]
# Format the results any way you want.
puts missing_nums.map { |ary| "#{ary.first}-#{ary.last}" }
鉴于您当前的语料库,这会在标准输出上产生以下结果:
1-4
9-14
18-24
答案 2 :(得分:2)
只需记住上一个数字并验证当前的数字是前一个加号:
#! /bin/bash
previous=0
while read n ; do
if (( n != previous + 1 )) ; then
echo $(( previous + 1 ))-$(( n - 1 ))
fi
previous=$n
done
您可能需要添加一些检查以防止28-28
等行出现单个数字空白。
答案 3 :(得分:2)
有趣的问题。
sputnick的awk单行很好。我不能写一个比他更简单的。我只是使用diff添加另一种方式:
seq $(tail -1 file)|diff - file|grep -Po '.*(?=d)'
您的示例的输出将是:
1,4
9,14
18,24
我知道其中有逗号,而不是-
。你可以用sed替换grep得到-
,grep不能改变输入文本......但是想法是一样的。
答案 4 :(得分:0)
Perl解决方案类似于StardustOne的awk解决方案:
perl -ane 'if ($F[0] != $p+1) {printf "%d-%d\n",$p+1,$F[0]-1}; $p=$F[0]' file.txt
使用以下命令行选项:
-n
循环输入文件的每一行,不自动打印每一行
-a
autosplit模式 - 将输入行拆分为@F数组。默认为在空格上拆分。字段从0开始编制索引。
-e
执行perl代码
答案 5 :(得分:0)
根据输入文件,使用文件旁边的numinterval
util和paste
输出,然后将其与tr
进行混合,{ {1}},xargs
和sed
:
printf
gaps() { paste <(echo; numinterval "$1" | tr 1 '-' | tr -d '[02-9]') "$1" |
tr -d '[:blank:]' | xargs echo |
sed 's/ -/-/g;s/-[^ ]*-/-/g' | xargs printf "%s\n" ; }
的输出:
gaps file
工作原理。 5-8
15-17
25-27
的输出如下:
paste <(echo; numinterval file) file
从那里我们主要替换第1列中的内容,并调整间距。 5
1 6
1 7
1 8
7 15
1 16
1 17
8 25
1 26
1 27
被1
替换,更高的数字被删除。使用-
删除一些空格。使用单个连字符“ 5-8 ”替换“ 5-6-7-8 ”等连字符的运行,这就是输出。