我有一个包含数字的文件,例如1到300.但数字不是连续的。示例文件如下所示
042
043
044
045
078
198
199
200
201
202
203
212
213
214
215
238
239
240
241
242
256
257
258
现在我需要检查数字序列的连续性,并相应地写出输出。例如,前4个数字是串联的,因此输出应为
042-045
接下来,078是一个单独的数字,因此输出应为
078
为方便起见,它可以看起来像
078-078
然后198到203是连续的。所以,下一个输出应该是
198-203
等等。最终输出应该像
042-045
078-078
198-203
212-215
238-242
256-258
我只需要知道连续系列的第一个和最后一个成员,并在遇到不连续时跳到下一个系列;输出可以被操纵。我倾向于使用if语句,可以想到像这样复杂的事情
num=`cat file | wc -l`
out1=`head -1 file`
for ((i=2;i<=$num;i++))
do
j=`echo $i-1 | bc`
var1=`cat file | awk 'NR='$j'{print}'`
var2=`cat file | awk 'NR='$i'{print}'`
var3=`echo $var2 - $var1 | bc`
if [ $var3 -gt 1 ]
then
out2=$var1
echo $out1-$out2
out1=$var2
fi
done
虽然有效,但过于冗长。我相信这样做肯定有一个简短的方法。 我也对shell,awk或几行fortran代码中的其他直接命令(或几个命令)持开放态度。
在期待中感谢你。
答案 0 :(得分:5)
这个awk one-liner适用于给定的例子:
awk 'p+1!=$1{printf "%s%s--",NR==1?"":p"\n",$1}{p=$1}END{print $1}' file
它为您的数据提供输出:
042--045
078--078
198--203
212--215
238--242
256--258
答案 1 :(得分:1)
以下是Fortran中的一个简单程序:
program test
implicit none
integer :: first, last, uFile, i, stat
open( file='numbers.txt', newunit=uFile, action='read', status='old' )
read(uFile,*,iostat=stat) i
if ( stat /= 0 ) stop
first = i ; last = i
do
read(uFile,*,iostat=stat) i
if ( stat /= 0 ) exit
if ( i == last+1 ) then
last = i
else
print *,first,'-',last
write(*,'(i3.3,a,i3.3)') first,'-',last
endif
enddo
write(*,'(i3.3,a,i3.3)') first,'-',last
end program
输出
042-045
078-078
198-203
212-215
238-242
256-258