将文件的特定部分写入另一个文件

时间:2015-08-30 15:35:58

标签: fortran

我正在编写一个代码来读取巨大的文件(文件XYZ),它有几个对象(比如A,B,C,D,E ......可能会有更多,每个对象有数百个数据文件)。现在我需要将文件读入Fortran并选择一个对象,例如'对象B',并将'对象B'的所有信息写入我使用fortran代码创建的新文件中。

每个对象(来自A -....)具有由头文件和数据数组组成的信息(矩阵(i,j),其中i对于每个文件而变化,并且j = 4)。我必须将头文件和数组数据都读入新文件中,并且这些对象(A -....)不是按顺序排序的(假设在A之后可能是C或D)。

我编写了一个小代码,但它似乎不能正常工作,因为我要么只能输出标题而不能输出数组,要么根本没有附加对象和代码的数据文件。

enter image description here

enter image description here

enter image description here

 program trail


   implicit none

    CHARACTER (LEN=5) :: thumb='3C286', SOURCE

    INTEGER :: pair(4), n,io, allocstat


   real, dimension(:,:),allocatable:: a



  CHARACTER (LEN=20) ::  POLCODE, DEC, RA 
  CHARACTER (LEN=40) :: TELESCOPE, NAME_MY, DATA_FILENAME, object , date,  TEXT, HEADER, restfreq,BANDWIDT, TSYS, OBSTIME, ANGLE
  character(len=180) :: Outdat
  character(len=75) :: ra_1, residu, flux, vlafit
  open(2, FILE='trail9.txt',POSITION='APPEND')

do
    open(1, File="column_3C286_iteration1.txt",status='old' )

     read(1,*), SOURCE


 10  if(Source.eq.'OJ287') then

   ! READING THE DATA   

      read(1,'(A40)') DATA_FILENAME
      read(1,'(A40)') TELESCOPE
      read(1,'(A40)') NAME_MY
      read(1,'(A40)') data_filename
      read(1,'(A40)') OBJECT
      read(1,'(A40)') restfreq
      read(1,'(A20)')  polcode
      read(1,'(A40)') angle
      read(1,'(A40)') date
      read(1,'(A40)') bandwidt
      read(1,'(A40)') tsys
      read(1,'(A40)') obstime
      read(1,'(A20)') ra
      read(1,'(A20)') dec
      read(1,'(A40)') text
      read(1,'(A40)')  header
      read(1,'(A180)') OUTDAT
      read(1,"(T2, A3,T30,A4, T50,A6,T67,A6)"),ra_1, residu, flux, vlafit



n=0

  do
    read(1,*,iostat=io) pair
    if (io/=0) exit
    n = n + 1
  end do


allocate(a(n,4),stat=allocstat)

do   i=1,n                                                                                 
    read(1,*)  (a(i,j),j=1,4 )                                              

  enddo 

 if  (index(data_filename,'#')>0 ) then 

!WRITING THE DATA

              write(2,'(A40)')  DATA_FILENAME

             write(2,'(A40)') TELESCOPE
            write(2,'(A40)') NAME_MY
            write(2,'(A40)') data_filename
            write(2,'(A40)') OBJECT
            write(2,'(A40)') restfreq
            write(2,'(A20)')  polcode
            write(2,'(A40)') angle
            write(2,'(A40)') date
            write(2,'(A40)') bandwidt
            write(2,'(A40)') tsys
            write(2,'(A40)') obstime
            write(2,'(A20)') ra
            write(2,'(A20)') dec
            write(2,'(A40)') text
            write(2,'(A40)')  header
                WRITE(2,'(A180)') OUTDAT
 Write(2,"(T2, A3,T30,A4, T50,A6,T67,A6)"),ra_1, residu, flux, vlafit


 do i=1,n

    write(2,"(T1,F10.4: T27,F10.4,T47, F10.4, T63,F10.4, T75,F10.4 )"), (a(i,j), j=1,4)

end do

end do
 end if


end do

end program trail

1 个答案:

答案 0 :(得分:1)

请尝试将pair的类型从整数更改为实数,并将代码修改为

real :: pair(4)
integer :: i

n = 0
do
    read(1,*,iostat=io) pair
    if (io/=0) exit
    n = n + 1
end do

do i = 1, n + 1
    backspace( 1 )
enddo 

这样,read语句对包含四个浮点数的行进行计数,并在行中找到非数字字符(如#)时停止读取。请注意backspace()执行n + 1次,以便文件指针返回当前数据部分的顶部。

虽然不是很确定,但我也认为以下公开声明

open(1, File="column_3C286_iteration1.txt",status='old' )
如果这对应于数据文件,则应在最外面的DO循环之前写入

总结一下,我建议进行以下修改:

real :: pair(4)
integer :: i

open(1, File="column_3C286_iteration1.txt",status='old' )

do
    read(1,*,end=5000), SOURCE     

    if( Source .eq.'OJ287' ) then

        ! read the remaining header and data lines in one block.

        read(1,'(A40)') DATA_FILENAME
        read(1,'(A40)') TELESCOPE
        ...
        read(1,"(T2, A3,T30,A4, T50,A6,T67,A6)"),ra_1, residu, flux, vlafit

        n = 0
        do
            read(1,*,iostat=io) pair
            if (io/=0) exit
            n = n + 1
        end do

        do i = 1, n + 1
            backspace( 1 )
        enddo    

        if ( allocated( a ) ) deallocate( a )
        allocate( a( n, 4 ) )

        do i = 1, n
            read( 1, * ) a( i, 1:4 )
        enddo

        !! write out the obtained data to file 2.
    endif
enddo
5000 continue

修改

如果我们只想复制一个"标题+数据"对于不同的文件,更简单地回显块中的所有行而不进行格式化。例如,程序可能如下所示。

character(200) :: str, field
integer :: ios
real :: dum
open( 10, file="input.dat", status="old" )

do
    read( 10, "(a)", end=5000 ) str

    if ( trim(str) == "OJ287" ) then     !! search for the target block

        print "(a)", trim(str)   !! print the tag

        !! read one block.                                                      
        do
            read( 10, "(a)", end=5000 ) str
            read( str, * ) field     !! get the first field of a line

            if ( field(1:1) == "#" .or. field(1:2) == "ra" ) then

                print "(a)", trim(str)  !! header part
            else
                read( str, *, iostat=ios ) dum   !! test if this line starts with a number
                if ( ios == 0 ) then
                    print "(a)", trim(str)  !! data part                        
                else
                    backspace( 10 )
                    exit
                endif
            endif
        enddo

    endif
enddo
5000 continue