使用if-else检查数字序列的连续性

时间:2016-05-09 14:51:59

标签: shell if-statement awk fortran

我有一个包含数字的文件,例如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代码中的其他直接命令(或几个命令)持开放态度。

在期待中感谢你。

2 个答案:

答案 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